【C言語】
西暦から干支を求める方法
ポインタポインタの使い方

ポインタが 分からない

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


■無駄にstrcpyをしている例

#include <stdio.h>
#include <string.h>
#include <assert.h>

void 西暦干支変換(int 西暦,char *干支){
    switch ( 西暦%12 ) {
    case  0: strcpy(干支,"申(さる)");     break;
    case  1: strcpy(干支,"酉(とり)");     break;
    case  2: strcpy(干支,"戌(いぬ)");     break;
    case  3: strcpy(干支,"亥(い)");       break;
    case  4: strcpy(干支,"子(ね)");       break;
    case  5: strcpy(干支,"丑(うし)");     break;
    case  6: strcpy(干支,"寅(とら)");     break;
    case  7: strcpy(干支,"卯(う)");       break;
    case  8: strcpy(干支,"辰(たつ)");     break;
    case  9: strcpy(干支,"巳(み)");       break;
    case 10: strcpy(干支,"午(うま)");     break;
    case 11: strcpy(干支,"未(ひつじ)");   break;
    default: assert(!"ここには来ない");     break;
    }
}
int main(void){
    const int 今年=2024;
	for(int 西暦 = 今年;西暦<=今年+12;西暦++){
        char    干支[256];
        西暦干支変換(西暦,干支);
        printf("%4d年の干支は%s\n",西暦,干支);
    }
}

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

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


■文字列のアドレスを直接使う

#include <stdio.h>
#include <string.h>
#include <assert.h>

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(!"ここには来ない");
    }
}
int main(void){
    const int 今年=2024;
	for(int 西暦 = 今年;西暦<=今年+12;西暦++){
        char    *干支 = 西暦干支変換(西暦);
        printf("%4d年の干支は%s\n",西暦,干支);
    }
}

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


ポインタポインタを使う

#include <stdio.h>
#include <string.h>
#include <assert.h>

void 西暦干支変換(int 西暦,char **干支){
    switch ( 西暦%12 ) {
    case  0: *干支 = "申(さる)";  break;
    case  1: *干支 = "酉(とり)";  break;
    case  2: *干支 = "戌(いぬ)";  break;
    case  3: *干支 = "亥(い)";    break;
    case  4: *干支 = "子(ね)";    break;
    case  5: *干支 = "丑(うし";    break;
    case  6: *干支 = "寅(とら)";  break;
    case  7: *干支 = "卯(う)";    break;
    case  8: *干支 = "辰(たつ)";  break;
    case  9: *干支 = "巳(み)";    break;
    case 10: *干支 = "午(うま)";  break;
    case 11: *干支 = "未(ひつじ)";break;
    default: assert(!"ここには来ない");
    }
}
int main(void){
    const int 今年=2024;
	for(int 西暦 = 今年;西暦<=今年+12;西暦++){
        char    *干支 = NULL ; 
        西暦干支変換(西暦,&干支);
        printf("%4d年の干支は%s\n",西暦,干支);
    }
}

●ポインタポインタ**を使った例です。
ちょっと難解です。

■配列を使う

#include <stdio.h>
#include <string.h>
#include <assert.h>
char *西暦干支変換(int 西暦){
    static char *干支[] ={
        [0]="申(さる)"    ,   
        [1]="酉(とり)"    ,   
        [2]="戌(いぬ)"    ,   
        [3]="亥(い)"      ,     
        [4]="子(ね)"      , 
        [5]="丑(うし)"    , 
        [6]="寅(とら)"    ,
        [7]="卯(う)"      ,         
        [8]="辰(たつ)"    , 
        [9]="巳(み)"      ,   
        [10]="午(うま)"   ,  
        [11]="未(ひつじ)" 
    };
    return      干支[西暦%12] ;
}
int main(void){
    const int 今年=2024;
	for(int 西暦 = 今年;西暦<=今年+12;西暦++){
        char    *干支 = 西暦干支変換(西暦);
        printf("%4d年の干支は%s\n",西暦,干支);
    }
}

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