第6章

第8章
ポインタ
◎変数名とアドレス
図8-1 メモリ上での変数の配置例
char mych = 55;
int mydt = 1234;
メモリ
変数mych
変数mydt
55
1234
1000番地
1001番地
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);
printf(“値 *pt =%d\n”, *pt);
ポインタ設定をする
ーmydtを表示
ー*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
*ptで値表現
メモリ
0012FEDC 1234
番地
変数mydt
リスト ポインタ内容を更新する例
int mydt1 = 1234, mydt2 = 5678;
int *pt;
pt = &mydt1;
printf(“値 *pt=%d\n”, +pt);
pt = &mydt2;
printf(“値 *pt=%d\n”, *pt);
ーmydt1のアドレスを設定
ー*ptを表示
ーmydt2のアドレスを設定
ー*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]
111
222
333
444
&ary[0] または ary
ary[1]
ary[2]
ary[3]
&ary[1]
&ary[2]
&ary[3]
リスト ポインタ演算をする
#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;
++pt;
ptはary[0]を指す
新しいptはary[1]を指す
111
ary[0]
222
ary[1]
リスト 文字列をポインタ処理する
#include <stdio.h>
#include <stdio.h> /* for tolower() */
int main(void)
{
char ss[10] = “ABCDE”;
char *ssp;
ーchar型の配列
ー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 配列名とポインタによる文字指定の方法
char ss[] = “ABCDE”;
char p = ss;
データ
‘A’
配列名
ss[0]
‘B’
ss[1]
*(p+1)
‘C’
ss[2]
*(p+2)
‘D’
ss[3]
*(p+3)
‘E’
ss[4]
*(p+4)
‘\0’
ss[5]
*(p+5)
pによる表現 ++pを行なうと
*p
すべて*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]) {
printf(“%x ”, ss[i]);
++i;
}
printf(“\n”);
}
ー配列を引数にする
ー文字列をそのまま出力する
ーss[i]が’\0’でない間ループする
ーss[i]を16進数出力
void strout_p(char *pp)
{
printf(“pp=%s\n”, pp);
while (*pp) {
printf(“%x ”, *pp);
++pp;
}
printf(“\n”);
}
ーポインタを引数にする
ー文字列をそのまま出力する
ー*ppが’\0’でない間ループする
ー*ppを16進数出力
ーポインタを進める