今日、C言語 char (*[])[]
と char *[][]
の違いに苦しんだ。
言葉にしてもわからないよ。
char ( * capa [2] ) [6]
サイズ6のCharの配列(文字列)へのポインタのサイズ2の配列。
char * cpaa [2] [6]
Charへのポインタのサイズ6の配列のサイズ2の配列。
考え方
識別子から優先度に従って矢印を書くと良さそう。
char (* capa [2]) [6] // capaから始まる。
char (* capa -> [2]) [6] // `[]`が優先。capaは配列(2)を指す。
char (* <- (capa -> [2])) [6] // `()`が優先。配列(2)はポインタが入る。
char (* <- (capa -> [2])) -> [6] // ポインタは配列(6)を指す。
char <- ((* <- (capa -> [2])) -> [6]) // 配列はcharが6個入る。
char * cpaa [2] [6] // cpaaから始まる。
char * cpaa -> [2] [6] // cpaaは配列(2)を指す。
char * cpaa -> [2] -> [6] // 配列(2)は配列(6)が入る。
char * <- (cpaa -> [2] -> [6]) // 配列(6)はポインタが入る。
char <- * <- (cpaa -> [2] -> [6]) // ポインタはcharを指す。
慣れてくると楽しくなってくる。
char *(*(*x[4])[5])[6]; // x = [4]*[5]*[6]*char
char *(*(*(*xp)[4])[5])[6]; // xp = *[4]*[5]*[6]*char
char ***y[4][5][6]; // y = [4][5][6]***char
char ***(*yp)[4][5][6]; // yp = *[4][5][6]***char
Sample code
https://onlinegdb.com/IgPBcDh__
#include <stdio.h>
int main() {
char hello[6] = "hello";
char world[6] = "world";
char(*capa[2])[6] = // capa = [2]*[6]char = [2]*string(6)
{&hello, &world};
printf("%p -> %s\n", capa[0], *capa[0]); // `hello`
printf("%p -> %s\n", capa[1], *capa[1]); // `world`
char a1 = 'a';
char a2 = 'b';
char a3 = 'c';
char a4 = 'd';
char a5 = 'e';
char a6 = 'f';
char b1 = 'g';
char b2 = 'h';
char b3 = 'i';
char b4 = 'j';
char b5 = 'k';
char b6 = 'l';
char *cpaa[2][6] = {// cpaa = [2][6]*char
{&a1, &a2, &a3, &a4, &a5, &a6},
{&b1, &b2, &b3, &b4, &b5, &b6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 6; j++) {
printf("%p -> %c\n", cpaa[i][j], *cpaa[i][j]);
}
}
return 0;
}
参考:
http://kmaebashi.com/programmer/pointer.html
K&R本: https://amzn.to/3ySLZZV