情報処理演習
第7回
11月12日
工学部6・7・8・9・10組
学籍番号末尾偶数
1
東北大学 大学院情報科学研究科
全 眞嬉
http://www.dais.is.tohoku.ac.jp/~jinhee/enshu-15.html
2
ポインタ
1.ポインタの基礎
→本日
2.数値データのポインタ →本日
3.文字データのポインタ →次回
メモリとアドレス
3
変数と配列
値を格納する方法について学んだ
格納した値は必要に応じてプログラムの中でいつで
も呼び出し可能
格納された値はメモリに保存される
メモリ
コンピュータ上で数値や文字などの値を保存して置く
装置
アドレス
メモリ上でどこに保存されているかを示す住所
変数に値を格納する
4
50
75
a[0][0]
a[0][1]
a[1][0]
a[1][1]
100
x
25
3
変数に値を格納する
=
ロッカーに荷物を入れる
ロッカーに荷物を入れる
5
ロッカーに荷物を入れる手順
空いているロッカーを探す
荷物を入れてカギを掛ける
ロッカーの番号を覚える
ロッカーから荷物を取り出す手順
番号でロッカーを探す
カギで開けて荷物を取り出す
ロッカー番号=メモリアドレス
6
ロッカーの番号は大切
効率的
番号が無ければ大量のロッカーから荷物を探すのは
大変
コンピュータでも同様
大量のデータが保存されているメモリから何の手が
かりなしで必要な情報を取り出すのはできない
アドレスを用いる
ロッカー
コンピュータ
番号
アドレス
メモリに変数の値を格納する
7
値が格納される場所
アドレス番号が必要
メモリ
変数x
x
100
データ型名
サイズ
char
1バイト
short
2バイト
int、 long
4バイト
float
4バイト
double
8バイト
格納される場所
4バイト
変数のアドレス
8
メモリ上の何番のアド
レスに変数が格納され
ているか
アドレス番号を気にす
る必要は無い
変数のアドレスを確認
&変数名
アドレスを表示させる
変換指定子
%p
/*ex22.c*/
#include<stdio.h>
main()
{
int x=100;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
}
変数のアドレス
9
int x=100;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
実行結果
x=100
address : ffbffc1c
変数xの値とメモリ上の
何番地に格納しているか
を確認
ffbffc1c
16進数
1バイト
変数のサイズを確認(sizeof演算子)
10
int x=100;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
printf("size : %d byte¥n",sizeof(x));
実行結果
x=100
address : ffbffc1c
size : 4byte
データ型名
サイズ
char
1バイト
short
2バイト
int、 long
4バイト
float
4バイト
double
8バイト
sizeof 演算子
型や変数のバイト数を調べられる
sizeof(変数名)
sizeof(x)
sizeof(型)
sizeof(int)
sizeof(double)
変数のアドレス
11
変数の値を変更し、
アドレスを確認
ex22.c を変更
xの値を200に変更
するプログラム
値を変更しても変数
のアドレスは変わら
ない
/*ex22.c*/
#include<stdio.h>
main()
{
int x=100;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
printf("size : %d byte¥n",sizeof(x));
x=200;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
printf("size : %d byte¥n",sizeof(x));
}
変数のアドレス
12
int x=100;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
printf("size : %d byte¥n",sizeof(x));
x=200;
printf("x = %d¥n",x);
printf("address : %p¥n",&x);
printf("size : %d byte¥n",sizeof(x));
実行結果
x=100
address : ffbffc1c
size : 4byte
x=200
address : ffbffc1c
size : 4byte
値を変更しても変数xのメモリ上の格納場所
であるアドレスは変わらない
格納される値のみ変更される
配列のアドレス
13
実行結果
a[0]= 100,
a[1]= 34,
a[2]= 78,
a[3]= 45,
a[4]= 98,
a[5]= 56,
a[6]= 100,
a[7]= 89,
a[8]= 94,
a[9]= 78,
address : ffbffbf4
address : ffbffbf8
address : ffbffbfc
address : ffbffc00
address : ffbffc04
address : ffbffc08
address : ffbffc0c
address : ffbffc10
address : ffbffc14
address : ffbffc18
/*ex23.c*/
#include<stdio.h>
main()
{
int i;
int a[10]={100,34,78,45,98,56,100,89,94,78};
for(i=0;i<10;++i)
printf(“a[%d]=%3d, address : %p¥n”,i,a[i],&a[i]);
}
配列におけるメモリ上のアドレス
14
メモリ
a[0]= 100, address : ffbffbf4
a[1]= 34, address : ffbffbf8
a[2]= 78, address : ffbffbfc
a[3]= 45, address : ffbffc00
a[4]= 98, address : ffbffc04
a[5]= 56, address : ffbffc08
a[6]= 100, address : ffbffc0c
a[7]= 89, address : ffbffc10
a[8]= 94, address : ffbffc14
a[9]= 78, address : ffbffc18
データ型名
サイズ
char
1バイト
short
2バイト
int、 long
4バイト
float
4バイト
double
8バイト
a[0] a[1] a[2] a[3] a[4] a[5] a[6] ・・・・
4byte 4byte 4byte 4byte 4byte 4byte 4byte
ポインタとは
15
変数の一種
アドレスを格納するための変数
ポインタと言う特殊の変数を用いることで、他の変
数たちが持つアドレスを格納することが可能
100
x
変数xの
アドレス
ffbffc1c
ポインタ
アドレスを格納できる変数
ポインタの変数の宣言
16
宣言方法
他の変数と同様ポインタ変数の宣言を行う
変数の名前の前に「*」を付ける
型名
*変数名;
int *p1;
float *p2;
char *p3;
宣言により変数
p1,p2,p3のポインタ変数が用意される
「*」はポインタ宣言時には付けるが、ポインタ名には「*」
を付けないので注意
ポインタの宣言と変数の宣言
17
ポインタ変数を宣言する際には必ず「*」を付ける
ポインタの宣言
int *a;
int b;
変数の宣言
ポインタの変数の宣言
18
ポインタを宣言する際に変数の型名を
指定
int型ポインタ、int*型
int *p1;
float型ポインタ、flaot*型
float *p2;
char *p3;
char型ポインタ、char*型
ポインタの型
19
変数のアドレスはその
変数の型に対応した
ポインタ変数にしか格
納できない
int型のポインタであるint*
型のポインタ変数のみに
そのアドレスの格納可能
100
int 型
x
ffbffc1c
○
int *型
変数xの
アドレス
×
float*型
ポインタを使うメリット
20
C言語でポインタを用いると
関数などで変数のアドレスを引数として渡すことがで
きる
文字列や配列をより便利に利用できる
その他の型を含めた動的なデータ構造を定義できる
ポインタへのアドレス代入
21
/*ex24.c*/
#include<stdio.h>
main()
{
int x;
int *p;
p=&x;
printf("address of x : %p¥n",&x);
printf("pointer p : %p¥n",p);
}
実行結果
address of x : ffbffc18
pointer p : ffbffc18
普通の変数か
ポインタ変数か
によって記述す
べき内容が異
なる
&x はxのアドレ
ス、&演算子を
利用した計算式
p はxのアドレス
を格納している
ポインタ変数
ポインタから変数の値を参照
22
ポインタに格納されているアドレスから、そこに格納
されている変数の値を取得
間接参照演算子 *
*ポインタ変数名;
ポインタ側からある変数に格納されている値を調べる
ex24.c を変更
下記を追加
x=100;
printf(“value of x : %d¥n",x);
printf("value of p : %d¥n",*p);
実行結果
address of x : ffbffc18
pointer p : ffbffc18
value of x : 100
value of p : 100
&演算子と*演算子と各変数の対応
23
&演算子
変数が格納されているアドレスを返す演算子
*演算子
ポインタからそのアドレスに格納されている値を返す演算子
/*ex24.c*/
#include<stdio.h>
main()
{
int x;
int *p;
p=&x;
printf("address of x : %p¥n",&x);
printf("pointer p : %p¥n",p);
x=100;
printf(“value of x : %d¥n",x);
printf("value of p : %d¥n",*p);
}
x
変数xの値
&x 変数xが格納されているア
ドレス
p
変数xのアドレスが格納さ
れているポインタ
&xのアドレス
と同じ
*p ポインタpが指すアドレスに xの値と同じ
格納されている変数の値
配列要素とアドレス
24
b[0]= 36.5
b[1]=38.4
b[2]=37.5
メモリ
b[0] b[1] b[2]
4byte 4byte 4byte
データ型名
サイズ
char
1バイト
short
2バイト
int、 long
4バイト
float
4バイト
double
8バイト
配列要素とアドレス
25
配列でのアドレス
配列の要素の前に&を付けると値が格納されているアドレ
スが分かる
配列名の演算によって各配列要素のアドレスを取得でき
る
&b[0],&b[1],&b[2]
b+1,b+2
配列のアドレスを求める方法
&を使う方法
配列名で指定する方法
&b[0]
&b[1]
&b[2]
b
b+1
b+2
b[0]= 36.5
b[1]=38.4
b[2]=37.5
配列要素とアドレス
26
/*ex25.c*/
#include<stdio.h>
main()
{
float b[3]={36.5, 38.4, 37.5};
printf("address of b[0]: %p, b : %p¥n",&b[0], b);
printf("address of b[1]: %p, (b+1): %p¥n",&b[1], (b+1));
printf("address of b[2]: %p, (b+2): %p¥n",&b[2], (b+2));
}
実行結果
address of b[0]: ffbffc14, b
: ffbffc14
address of b[1]: ffbffc18, (b+1): ffbffc18
address of b[2]: ffbffc1c, (b+2): ffbffc1c
配列のアドレスから値を調べる
27
変数の場合と同様に配列要素に関してもアドレス
情報から格納されている値を取得可能
間接演算子*を利用
*b
*(b+1)
*(b+2)
注意
0番地以外は()を忘れずに付ける
*(b+1)
*b+1
配列のアドレスから各配列要素の値を参照
28
/*ex26.c*/
#include<stdio.h>
main()
{
int i;
float b[3]={36.5, 38.4, 37.5};
for(i=0;i<3;++i)
printf("value of b[%d]: %3.1f, value of *(b+%d): %3.1f¥n",i,b[i],i, *(b+i));
}
実行結果
value of b[0]: 36.5, value of *(b+0): 36.5
value of b[1]: 38.4, value of *(b+1): 38.4
value of b[2]: 37.5, value of *(b+2): 37.5
配列における記述法の比較(先頭要素の場合)
29
配列要素での指定
値
b[0]
アドレス &b[0]
配列名での指定
*b
b
ポインタはアドレスを指し示すための変数
配列bに関してはbと記述することで配列が確保してい
るメモリの中の先頭のアドレスを取得できる
つまり、bは配列の先頭要素のアドレスが格納されてい
るポインタ変数でもある
演習1
30
/*ex27.c*/
/*学籍番号:
名前:
*/
/*ポインタが指す変数の値の表示*/
#include<stdio.h>
main()
{
int i=10;
int *p;
/*int型変数を指すポインタpの宣言*/
p=&i;
/*ポインタpに変数iのアドレスを代入*/
printf("%d ¥n",*p);
/*ポインタpの指す変数の値を表示*/
*p=10*(*p);
/*ポインタpの指す変数の値を10倍にする*/
printf("%d ¥n",*p);
/*ポインタpの指す変数の値を表示*/
}
実行結果
10
100
演習2
31
/*ex28.c*/
/*学籍番号:
名前:
*/
/*ポインタが指す変数の計算*/
#include<stdio.h>
main()
{
int a=10;
int b=5;
int c;
int *pa ;
/*aへのポインタpaを宣言*/
int *pb ;
/*bへのポインタpbを宣言*/
pa= &a ;
/*アドレス演算子によりaのアドレスをpaに代入*/
pb= &b ;
/*アドレス演算子によりbのアドレスをpbに代入*/
c=*pa + *pb;
printf("a+b=%d¥n",c);
}
実行結果
a+b=15
© Copyright 2026 ExpyDoc