300 likes | 478 Views
第8章. ポインタ. 1234. 55. ◎ 変数名とアドレス. 図8-1 メモリ上での変数の配置例. char mych = 55; int mydt = 1234;. メモリ. 1000 番地. 変数 mych. 1001 番地. 変数 mydt. 1002 番地. 1003 番地. 1004 番地. リスト 変数のアドレスを見る. #include <stdio.h> int main(void) { int mydt; mydt = 1234; printf(“mydt=%d<br>”, mydt); -変数の値を表示
E N D
第8章 ポインタ
1234 55 ◎変数名とアドレス 図8-1 メモリ上での変数の配置例 char mych = 55; int mydt = 1234; メモリ 1000番地 変数mych 1001番地 変数mydt 1002番地 1003番地 1004番地
リスト 変数のアドレスを見る #include <stdio.h> int main(void) { int mydt; mydt = 1234; printf(“mydt=%d\n”, mydt);-変数の値を表示 printf(“mydtのアドレス=%p\n”, &mydt);ー変数のアドレスを表示 return 0; }
ポインタ int *pt; ーポインタptの宣言 int *a, *b;-ポインタaとポインタpの宣言 pt = &mydt; ー変数mydtのアドレスをポインタptに代入
リスト 変数アドレスとポインタ内容を表示するリスト 変数アドレスとポインタ内容を表示する int *pt; ーポインタを宣言 int mydt = 1234; ー通常変数の宣言 pt = &mydt; ーアドレスを代入 printf(“アドレス&mydt=%p\n”, &mydt);ー&mydtを表示 printf(“アドレスpt =%p\n”, pt); -ptを表示
リスト ポインタで値を指定する int *pt; int mydt = 1234; ポインタ設定をする pt = &mydt; printf(“値 mydt=%d\n”, mydt); ーmydtを表示 printf(“値 *pt =%d\n”, *pt); ー*ptを表示
リスト ポインタと変数の関係を見る #include <stdio.h> int main(void) { int *pt int mydt = 1234, idt; pt = &mydt; ーアドレス設定 idt = *pt; ー*ptを一般変数に代入 printf(“値 mydt=%d\n”, mydt);ーmydtを表示 printf(“値 *pt =%d\n”, *pt);ー*ptを表示 printf(“値 idt =%d\n”, idt);ーidtを表示
mydt = 555; ー変数mydtの値を変更 printf(“値 mydt=%d\n”, mydt);ーmydtを表示 printf(“値 *pt =%d\n”, *pt);ー*ptを表示 *pt = 666; ー*ptの値を変更 printf(“値 mydt=%d\n”, mydt);ーmydtを表示 printf(“値 *pt =%d\n”, *pt);ー*ptを表示 return 0; }
変数とポインタの関係 int *pt, mydt = 1234; pt = &mydt; ポインタ メモリ *ptで値表現 0012FEDC 1234 0012FEDC番地 pt 変数mydt
リスト ポインタ内容を更新する例 int mydt1 = 1234, mydt2 = 5678; int *pt; pt = &mydt1; ーmydt1のアドレスを設定 printf(“値 *pt=%d\n”, +pt); ー*ptを表示 pt = &mydt2; ーmydt2のアドレスを設定 printf(“値 *pt=%d\n”, *pt); ー*ptを表示
◎ポインタ演算子 すでに記述例を示しましたが、ポインタを操作するために、ふたつのポインタ演算子が用意されています。それを次に整理します。 図8-1 ポインタ演算子 & 変数のアドレスを取り出す * そのポインタの指示するアドレスにある値を取り出す
図8-2 ポインタ演算子の覚えかた 演算子 意味 覚え方 & アドレスを取り出す アンド → アドレス * 値を取り出す アスタリスク → アタイ
⑧.3 配列とポインタ リスト 配列のアドレス表現を確認する #include <stdio.h> int main(void) { int ary[4] = {111, 222, 333, 444}; int *pt; pt = &ary; ー先頭アドレス&ary[0]と同じ printf(“値 *pt=%d\n”, *pt);ー*ptを表示 printf(“アドレス pt=%p\n”, pt); ーptを表示
pt = &ary[0]; ーary[0]のアドレス printf(“値 *pt=%d\n”, *pt); ー*ptを表示 printf(“アドレス pt=%p\n”, pt); ーptを表示 pt = &ary[1]; ーary[1]のアドレス printf(“値 *pt=%d\n”, *pt); ー*ptを表示 printf(“アドレス pt=%p\n”, pt); ーptを表示 pt = &ary[2]; ーary[2]のアドレス printf(“値 *pt=%d\n”, *pt); ー*ptを表示 printf(“アドレス pt=%p\n”, pt); ーptを表示 return 0; }
図8-3 配列のアドレス表現 int ary[4] = {111, 222, 333, 444}; 変数名 内容 アドレス表現方法 ary[0] ary[1] ary[2] ary[3] &ary[0] または ary &ary[1] &ary[2] &ary[3] 111 222 333 444
リスト ポインタ演算をする #include <stdio.h> int main(void) { int ary[4] = {111, 222 333, 444}; int *pt; pt = &ary; ー先頭アドレス設定 while (1) { printf(“値 *pt=%d\n”, *pt);ー++ptを繰り返しながら値表示 if (+pt == 444) break; ーループ終了 ++pt; ーポインタ更新 }
pt = ary; ー再び先頭アドレス設定 printf(“値 *pt =%d\n”, *pt); ー*ptを表示 printf(“値 *(pt+1)=%d\n”, *(pt+1));ー*(pt+1)を表示 printf(“値 *(pt+2)=%d\n”, *(pt+2));ー*(pt+2)を表示 return 0; }
ポインタの更新 int *pt, ary[4] = {111, 222, 333, 444}; ptはary[0]を指す 111 pt=ary; ary[0] 222 ++pt; ary[1] 新しいptはary[1]を指す
リスト 文字列をポインタ処理する #include <stdio.h> #include <stdio.h> /* for tolower() */ int main(void) { char ss[10] = “ABCDE”; ーchar型の配列 char *ssp; ーchar型を操作するポインタ ssp = ss; ー文字配列ssの先頭アドレスをsspに設定 printf(“文字列ss =%s\n”, ss); ーssで文字列出力 printf(“文字列ssp=%s\n”, ssp); ーsspで文字列出力 printf(“文字 *ssp =%c\n”, *ssp);ー先頭の文字を出力 printf(“文字 *(ssp+1)=%c\n”, *(ssp+1));ー次の文字を出力
while (*ssp != ‘0’) { ーナル文字までループ *ssp = tolower(*ssp); ー小文字にする ++ssp; ーポインタを進める } ssp = ss; ー再びssの先頭アドレスをsspに設定 printf(“文字列ss =%s\n”, ss); ーssで文字列出力 printf(“文字列ssp=%s\n”, ssp); ーsspで文字列出力 return 0; }
図8-4 配列名とポインタによる文字指定の方法図8-4 配列名とポインタによる文字指定の方法 char ss[] = “ABCDE”; char p = ss; データ 配列名 pによる表現 ++pを行なうと ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ ‘\0’ ss[0] ss[1] ss[2] ss[3] ss[4] ss[5] *p *(p+1) *(p+2) *(p+3) *(p+4) *(p+5) すべて*pで表現できる
リスト 関数にポインタを渡す #include <stdio.h> void func(int *dt); int main(void) { int nn; nn = 1234; func(&nn); ー変数nnのアドレスを渡す return 0; } void func(int *dt) ーポインタを仮引数にする { printf(“dt=%d\n”, *dt); ーポインタdtを使って値表示 }
リスト ポインタ引数で値を戻す関数 #include <stdio.h> void ava_p(double x, double y, double *ans); int main(void) { double a, b, avdt; a = 11.11; b = 33.33; ave_p(a, b, &avdt); ーaとbの平均値をavdtに入れる printf(“a=%f b=%f 平均=%f\n”, a, b, avdt); return 0; }
void ave_p(double x, double y, double *ans)ー引数ansをポインタ{ にする double wk; wk = (x + y) / 2.0; *ans = wk; ーwkの値を引数ansで戻す }
値を戻すふたつの方法 仮引数ポインタで戻す return文で戻す int fund1(int dt) { ・・・ return xx; } void func2(int *dt) { ・・・ *dt = xx; }
リスト ポインタで文字列を関数に渡すプログラムリスト ポインタで文字列を関数に渡すプログラム #include <stdio.h> void strout(char ss[]); void strout_p(char *ss); int main(void) { char st[] = “ABCDEF”; strout(st); ー文字配列を渡す strout(“ABab12”); ー直接文字列を渡す strout_p(st); ー文字配列を渡す strout_p(”ABab12”); ー直接文字列を渡す return 0; }
void strout(char ss[]) ー配列を引数にする { int i; printf(“ss=%s\n”, ss); ー文字列をそのまま出力する i = 0; while (ss[i]) { ーss[i]が’\0’でない間ループする printf(“%x ”, ss[i]); ーss[i]を16進数出力 ++i; } printf(“\n”); }
void strout_p(char *pp) ーポインタを引数にする { printf(“pp=%s\n”, pp); ー文字列をそのまま出力する while (*pp) { ー*ppが’\0’でない間ループする printf(“%x ”, *pp); ー*ppを16進数出力 ++pp; ーポインタを進める } printf(“\n”); }