【C言語入門】
西暦から干支を求める方法
そのコピーは無駄だ

警告:ポインタの理解不足で無駄にコピー(strcpy)してる


■無駄なコピーをしている例

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
void 西暦干支変換strcpy版(int 西暦,char *output){
    switch ( 西暦%12 ) {
    case  0: strcpy(output,"申(さる)");   break;
    case  1: strcpy(output,"酉(とり)");   break;
    case  2: strcpy(output,"戌(いぬ)");   break;
    case  3: strcpy(output,"亥(い)");     break;
    case  4: strcpy(output,"子(ね)");     break;
    case  5: strcpy(output,"丑(うし)");   break;
    case  6: strcpy(output,"寅(とら)");   break;
    case  7: strcpy(output,"卯(う)");     break;
    case  8: strcpy(output,"辰(たつ)");   break;
    case  9: strcpy(output,"巳(み)");     break;
    case 10: strcpy(output,"午(うま)");   break;
    case 11: strcpy(output,"未(ひつじ)"); break;
    default: assert(0);break;
    }
}
void 干支表示(int year){
    for(int i = 0;i < 12+1;i++){
        char    output[256];
        西暦干支変換strcpy版(year+i,output);
        printf("%d+%2d年の干支は%s\n",
            year,
            i, 
            output
        );
    } 
}
int main(void){
	time_t t = time(NULL);
	struct tm *local = localtime(&t);
	printf("%04d/", 	local->tm_year + 1900);
	printf("%02d/", 	local->tm_mon + 1);
	printf("%02d\n", 	local->tm_mday);
	干支表示(local->tm_year + 1900);
}

意図した動きをしますが
記述量が多くて、
処理速度も遅いです。。

strcpyで文字列を出力配列に
わざわざコピーしていますが無駄です


■文字列リテラルのアドレスを直接使う

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
static char *西暦干支変換文字列版(int 西暦){
    switch ( 西暦%12 ) {
    case  0: return     "申(さる)";   
    case  1: return     "酉(とり)";   
    case  2: return     "戌(いぬ)";   
    case  3: return     "亥(い)"  ;    
    case  4: return     "子(ね)"  ;     
    case  5: return     "丑(うし)";   
    case  6: return     "寅(とら)";   
    case  7: return     "卯(う)"  ;     
    case  8: return     "辰(たつ)";   
    case  9: return     "巳(み)"  ;     
    case 10: return     "午(うま)";   
    case 11: return     "未(ひつじ)"; 
    default:
        assert(0);
    }
}
static void 干支(int year){
    for(int i = 0;i < 12+1;i++){
        printf("%d+%2d年の干支は%s\n",
            year,
            i, 
            西暦干支変換文字列版(year+i)
        );
    } 
}
int main(void){
	time_t t = time(NULL);
	struct tm *local = localtime(&t);
	printf("%04d/", 	local->tm_year + 1900);
	printf("%02d/", 	local->tm_mon + 1);
	printf("%02d\n", 	local->tm_mday);
	干支(local->tm_year + 1900);
}

strcpyでコピーしないで
文字列を直接返却しているので
strcpy版より効率が良いです。


■配列を使う

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
static const char *西暦干支変換配列版(int 西暦){
    static const char *干支[] ={
        [0]="申(さる)"    ,   
        [1]="酉(とり)"    ,   
        [2]="戌(いぬ)"    ,   
        [3]="亥(い)"      ,     
        [4]="子(ね)"      , 
        [5]="丑(うし)"    , 
        [6]="寅(とら)"    ,
        [7]="卯(う)"      ,         
        [8]="辰(たつ)"    , 
        [9]="巳(み)"      ,   
        [10]="午(うま)"   ,  
        [11]="未(ひつじ)" 
    };
    return      干支[西暦%12] ;
}
static void 干支(int year){
    for(int i = 0;i < 12+1;i++){
        printf("%d+%2d年の干支は%s\n",
            year,
            i, 
            西暦干支変換配列版(year+i)
        );
    } 
}
int main(void){
	time_t t = time(NULL);
	struct tm *local = localtime(&t);
	printf("%04d/", 	local->tm_year + 1900);
	printf("%02d/", 	local->tm_mon + 1);
	printf("%02d\n", 	local->tm_mday);
	干支(local->tm_year + 1900);
}

●switch文が不要になりました。
このコードは記述量も少なく、
処理速度も多分最速です。