C言語の配列とか添え字演算子とかポインタとか
どうもポインタの理解が甘いので復習してみたが、訳が分からない。ポインタのポインタ(ダブルポインタ)とかポインタのポインタのポインタ(トリプルポインタ)とかイミフ。
以下、ソースコード。
#include <stdio.h> #include <stdlib.h> typedef struct aa { char c; struct aa *a; } aa; int main(void) { int i[] = {0, 1, 2, 3}; int *ip = i; int **ipp1 = &ip; int **ipp2[2] = {&ip, }; int *j = malloc(sizeof(int) * 4); j[0] = 900; j[1] = 8000; j[2] = 70000; j[3] = 600000; int **jpp = malloc(sizeof(int *) * 4); jpp[0] = j + 3; jpp[1] = j + 2; jpp[2] = j + 1; jpp[3] = &j[0]; int ***jppp = &jpp; aa z = {'z', NULL}; aa *a = malloc(sizeof(aa)); aa *ap = a; aa **app1 = ≈ aa **app2[2] = {&ap}; aa **app3 = malloc(sizeof(aa *) * 3); a->a = malloc(sizeof(aa)); a->a->a = NULL; app2[1] = &(a->a); app3[0] = NULL; app3[1] = ap; app3[2] = &z; a->c = 'l'; a->a->c = 'Q'; printf("i[0]\t\t == %d\n", i[0]); printf("ip[1]\t\t == %d\n", ip[1]); printf("*(ip + 2)\t\t == %d\n", *(ip + 2)); printf("**ipp1\t\t == %d\n", **ipp1); printf("*(*ipp1 * 2)\t\t == %d\n", *(*ipp1 + 2)); printf("*(*ipp2[0] + 3)\t\t == %d\n", *(*ipp2[0] + 3)); puts(""); printf("***jppp\t\t == %d\n", ***jppp); printf("**(jppp[0])\t\t == %d\n", **(jppp[0])); printf("**(*jppp + 1)\t\t == %d\n", **(*jppp + 1)); printf("*(jppp[0][2])\t\t == %d\n", *(jppp[0][2])); printf("jppp[0][3][0]\t\t == %d\n", jppp[0][3][0]); puts(""); printf("j\t\t == %p\n", j); printf("&j\t\t == %p\n", &j); printf("jpp\t\t == %p\n", jpp); printf("*(jpp + 3)\t\t == %p\n", *(jpp + 3)); printf("&jpp\t\t == %p\n", &jpp); printf("jppp\t\t == %p\n", jppp); printf("&jppp\t\t == %p\n", &jppp); puts(""); puts("aはポインタ"); printf("a->c\t\t == %c\n", a->c); printf("a->a->c\t\t == %c\n", a->a->c); printf("a->a->a\t\t == %p\n", a->a->a); puts(""); puts("apはポインタ"); printf("(*ap).c\t\t == %c\n", (*ap).c); printf("(&(*ap))->c\t\t == %c\n", (&(*ap))->c); printf("(*ap).a->c\t\t == %c\n", (*ap).a->c); printf("(*(ap->a)).a\t\t == %p\n", (*(ap->a)).a); printf("(*(*ap).a).c\t\t == %c\n", (*(*ap).a).c); puts(""); puts("app1はポインタのポインタ"); printf("(*(*app1)).c\t\t == %c\n", (*(*app1)).c); printf("(*app1)->c\t\t == %c\n", (*app1)->c); printf("(*(*app1)).a->c\t\t == %c\n", (*(*app1)).a->c); printf("(*(*app1)->a).c\t\t == %c\n", (*(*app1)->a).c); printf("(*app1)->a->c\t\t == %c\n", (*app1)->a->c); printf("((**app1).a)->a\t\t == %p\n", ((**app1).a)->a); printf("(*(*(*app1)).a).c\t\t == %c\n", (*(*(*app1)).a).c); puts(""); puts("app2はポインタのポインタの配列"); printf("(*(*app2[0])).c\t\t == %c\n", (*(*app2[0])).c); printf("(*app2[0])->c\t\t == %c\n", (*app2[0])->c); printf("(*(*app2[0])).a->c\t\t == %c\n", (*(*app2[0])).a->c); printf("(*(*app2[0])->a).c\t\t == %c\n", (*(*app2[0])->a).c); printf("(app2[0][0]->a)->a\t\t == %p\n", (app2[0][0]->a)->a); printf("(*(app2[0][0]->a)).a\t\t == %p\n", (*(app2[0][0]->a)).a); printf("(*((*(app2[0][0])).a)).a\t\t == %p\n", (*((*(app2[0][0])).a)).a); printf("(**app2)->c\t\t == %c\n", (**app2)->c); printf("(**(app2 + 1))->c\t\t == %c\n", (**(app2 + 1))->c); printf("(***app2).c\t\t == %c\n", (***app2).c); printf("(***(app2 + 1)).c\t\t == %c\n", (***(app2 + 1)).c); printf("(***app2).a->a\t\t == %p\n", (***app2).a->a); printf("*(***app2).a).c\t\t == %c\n", (*(***app2).a).c); puts(""); puts("app3はポインタのポインタ * 3"); printf("(*(*(app3 + 1))).c\t\t == %c\n", (*(*(app3 + 1))).c); printf("(**(app3 + 1)).c\t\t == %c\n", (**(app3 + 1)).c); printf("(*(app3 + 1))->c\t\t == %c\n", (*(app3 + 1))->c); printf("(*(app3 + 1))->a->c\t\t == %c\n", (*(app3 + 1))->a->c); printf("(**(app3 + 1)).a->c\t\t == %c\n", (**(app3 + 1)).a->c); printf("(*(**(app3 + 1)).a).a\t\t == %p\n", (*(**(app3 + 1)).a).a); printf("(*(*(app3[1])).a).c\t\t == %c\n", (*(*(app3[1])).a).c); printf("(*(app3[1]->a)).c\t\t == %c\n", (*(app3[1]->a)).c); printf("(app3[1][0].a)->c\t\t == %c\n", (app3[1][0].a)->c); printf("app3[2]->c\t\t == %c\n", app3[2]->c); printf("app3[0]\t\t == %p\n", app3[0]); free(a->a); free(a); free(app3); free(j); free(jpp); return 0; }
実行するとこうなる。
i[0] == 0 ip[1] == 1 *(ip + 2) == 2 **ipp1 == 0 *(*ipp1 * 2) == 2 *(*ipp2[0] + 3) == 3 ***jppp == 600000 **(jppp[0]) == 600000 **(*jppp + 1) == 70000 *(jppp[0][2]) == 8000 jppp[0][3][0] == 900 j == 0x8fb0008 &j == 0xbf83cb80 jpp == 0x8fb0020 *(jpp + 3) == 0x8fb0008 &jpp == 0xbf83cb84 jppp == 0xbf83cb84 &jppp == 0xbf83cb88 aはポインタ a->c == l a->a->c == Q a->a->a == (nil) apはポインタ (*ap).c == l (&(*ap))->c == l (*ap).a->c == Q (*(ap->a)).a == (nil) (*(*ap).a).c == Q app1はポインタのポインタ (*(*app1)).c == l (*app1)->c == l (*(*app1)).a->c == Q (*(*app1)->a).c == Q (*app1)->a->c == Q ((**app1).a)->a == (nil) (*(*(*app1)).a).c == Q app2はポインタのポインタの配列 (*(*app2[0])).c == l (*app2[0])->c == l (*(*app2[0])).a->c == Q (*(*app2[0])->a).c == Q (app2[0][0]->a)->a == (nil) (*(app2[0][0]->a)).a == (nil) (*((*(app2[0][0])).a)).a == (nil) (**app2)->c == l (**(app2 + 1))->c == Q (***app2).c == l (***(app2 + 1)).c == Q (***app2).a->a == (nil) *(***app2).a).c == Q app3はポインタのポインタ * 3 (*(*(app3 + 1))).c == l (**(app3 + 1)).c == l (*(app3 + 1))->c == l (*(app3 + 1))->a->c == Q (**(app3 + 1)).a->c == Q (*(**(app3 + 1)).a).a == (nil) (*(*(app3[1])).a).c == Q (*(app3[1]->a)).c == Q (app3[1][0].a)->c == Q app3[2]->c == z app3[0] == (nil)