プログラムの制御構造 選択・繰り返し

ポインタとポインタを用いた関数定義
Quiz
Q1.
int main(void)
{
int a=1, b=0;
{
int a=2;
b=b+a;
}
b=a+b;
Q2.
int main(void)
{
int a, b=0;
for(a=0;a<2;a++){
static int b=0;
b=a+b;
}
printf(“%d\n”,b);
printf(“%d\n”,b);
}
}
前回の復習
• 関数の定義
• 変数の有効範囲
• 関数の再帰的定義と再帰呼び出し
変数の属性
名前

値
アド レ ス ( 値の格納場所)
変数 
型( 格納領域の大き さ : バイ ト 数)
記憶のク ラ ス

有効範囲
例
8bit = 1byte(バイト)
0000H
main(){
int a;  ①
0001H
0002H
0003H
a = 33; /* 33(10) =0021(16) */  ②
a: 0 0 1 0 0 0 0 1 0004H
2バイト
0 0 0 0 0 0 0 0
(sizeof演算子で入手)
① aのアドレスが決まる(例の場合は0004H)
メモリ
② アドレス0004に33に相当する値が格納される
(auto変数のアドレスは関数呼び出し時に、static変数はプログラム実行時に決定)
ポインタ変数とアドレス計算
• アドレス演算子&を用いる
前の例では&aは0004Hとなる。
アドレスを陽に記憶するためにはアドレスを値として格納す
る変数が必要!
ポインタ型変数:アドレスを値として持つ変数
なぜア ド レ ス 型変数と 呼ばないか?
ア ド レ ス
ポイ ン タ =
型の情報( 型に対する データ サイ ズの 情報)
ポインタ変数の宣言と使い方
・型名 *変数名{,*変数名;}
int a;
int* p; /* int *p; */
p=& a; (p  0004H)
p++;
(p  0006H) /* p  0005H*/
/* p = p + sizeof(int) */
注意:
配列名は配列の最初の要素が
格納されているアドレスであり、
ポインタ型の定数である。
Int data[10], *p;
p=data;
間接参照演算子*
• ポインタ変数の「値」が指すアドレスの中身を取り出したり、逆に格納する
ための演算子。
変数の名前を用いずに変数の値を使うことが可能に!
②
①
int main(){
a:
int a;
int* p;
0
2
0004H
0
1
0005H
0006H
p:
int b;
a=258; /* 258(10) =0102H*/  ①  p=1;  ④
printf("% d % d \n", a, b);
}
p:
0007H
0008H
b:
0
2
0004H
0
1
0005H
0
4
0006H
0
0
0007H
0008H
b:
0009H
0009H
変数名aを使わずに値が使われた,変更された!
p=&a;  ②
b=  p;  ③
a:
④
③
a: 0
1 0004H
a: 変数のアドレスを使うことにより、明示的に
0
2 0004H
0
0 0005H
変数名を使わずに値を参照したり、変更できる。
0
1 0005H
p:
b:
0
4
0006H
0
0
0007H
0
2
0008H
0
1
0009H
p:
b:
0
4
0006H
0
0
0007H
0
2
0008H
0
1
0009H
配列とポインタ
main(){
int data[3],  p;  ①
p = data;  ②
 (p+1) = 2; /* data[1]=2; */  ③
②
①
③
0009H
0009H
data[0]:
data[1]:
p:
000AH
000AH
data[0]:
0009H
000AH
data[0]:
000BH
000BH
000CH
000CH
000DH
000DH
000EH
000EH
000EH
000FH
000FH
000FH
0010H
0011H
p:
0
A
0010H
0
0
0011H
000BH
data[1]:
p:
0
2
000CH
0
0
000DH
0
A
0010H
0
0
0011H
ポインタ変数を用いた関数定義(1)
• ポインタ変数を用いる理由
1. 関数を呼び出して関数の値として結果を返すと、
1つの値しか返せない
2. 値を渡さないでそのあり場所(アドレス)を渡した
方が処理が速い場合がある
3. 関数を一度だけ呼び出して、呼び出し側の変数
の値を複数個変更できる
その他の方法
① 大域変数を使う(バグの元)
② 配列を使う(同じ型の結果のみ)
関数に2つアドレスを渡して値をコピーするプログラム
main(){
a:
int a=2,b;
equal(&b,&a);
b:
0
2
0004H
p1: 0
6
0004H
0
0
0005H
0
0
0005H
0
2
0006H
4
0006H
0
0
0007H
p2: 0
0
0
0007H
}
void equal(int* p1, int* p2)
{
0008H
0008H
0009H
0009H
*p1=*p2;
}
*p1=*p2 →
*p1=2 →
*(0006)=2
ポインタ変数を用いた関数定義(1)
2つの整数の和と積を1つの関数を呼び出すだけで計算する
大域変数の使用
int a,b,c,d;
配列の使用
main(){
ポインタの使用
main(){
int data[4];
int a, b, c, d;
a = 1;
data[0] = 1;
a = 1;
b = 2;
data[1] = 2;
b = 2;
addmul(data);
addmul(a, b, &c, &d);
main(){
addmul();
void addmul()
{
c = a + b;
void addmul(int x[])
void addmul(int x, int y, int  p1, int  p2)
{
{
d = a * b;
}
}
x[2] = x[0] + x[1];
 p1 = x + y;
x[3] = x[0]*x[1];
 p2 = x  y;
}