読者です 読者をやめる 読者になる 読者になる

C言語の関数の引数が配列であるときの不思議

C言語で、関数の引数に配列が入っている場合。

例えば Ruby

stg = "Hello, World!"
puts stg

と書くのを、C言語では

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

int main(void)
{
    char stg[20];
    strcpy(stg, "Hello, World!\n");
    printf("%s", stg);
    return 0;
}

となるのか(追記)。面倒だが、これは問題ない。けれども、

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

void getstg(char s[])
{
    strcpy(s, "Hello, World!\n");
    return;
}

int main(void)
{
    char stg[20];
    getstg(stg);
    printf("%s", stg);
    return 0;
}

でちゃんと「Hello, World!」が出力されるのは不思議。関数呼び出しの getstg(stg);str[] が、呼び出しで書き換えられるわけか。ちょっと意外。

では、同じく

#include <stdio.h>

void getnum(int n[])
{
    n[0] = 5; n[1] = 4; n[2] = 3;
    n[3] = 2; n[4] =1;
    return;
}

int main(void)
{
    int m[5] = {1, 2, 3, 4, 5};
    getnum(m);
    for (int i = 0; i < 5; i++){
        printf("%d  ", m[i]);
    }
    return 0;
}

の出力も、

5  4  3  2  1

となるわけね。ここで変数 m, n というのは、ポインタみたいなものか(※追記 やはり大凡そうでした。ちゃんと勉強しよう)。しかし、配列でない場合は、次の

#include <stdio.h>

void getnum(int n)
{
    n = 2;
    return;
}

int main(void)
{
    int m = 1;
    getnum(m);
    printf("%d", m);
    return 0;
}

の出力は、期待されるとおり「1」で、「2」ではない。

蛇足だが、もちろん Ruby では、

def getnum(n)
  n = [5, 4, 3, 2, 1]
end

m = [1, 2, 3, 4, 5]
getnum(m)
p m

の出力は「[1, 2, 3, 4, 5]」となって、C言語とはちがう。



※追記
別に以下でもよかったです。考えすぎでした。

#include <stdio.h>

int main(void){
    char stg[] = "Hello, World!\n";
    printf("%s", stg);
    return 0;
}

ついでに。二次元配列でこんなことも可能。

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

int main(void)
{
    char s[8][30];
    
    strcpy(s[0], "The year's at the spring,\n");
    strcpy(s[1], "And day's at the morn;\n");
    strcpy(s[2], "Morning's at seven;\n");
    strcpy(s[3], "The hill-side's dew-pearl'd;\n");
    strcpy(s[4], "The lark's on the wing;\n");
    strcpy(s[5], "The snail's on the thorn;\n");
    strcpy(s[6], "God's in His heaven--\n");
    strcpy(s[7], "All's right with the world!\n");
    
    for (int i = 0; i < 8; i++){
      printf("%s", s[i]);
    }
    return 0;
}