PowerPoint プレゼンテーション - Multi Media Club

メモリ上の番地アドレスから遡って、変数の値
を見ていったりするする
第10章 ポインタ
1



文字を変数に入れるための char 型
文字列は配列を使い、その最後には『\0』が終
了点として必ず付けられる
コンピュータ内で文字と整数値は対応しており、
それは文字コードに則って決められている
第10章 ポインタ
2

アドレスとポインタ
変数のアドレスとポインタ変数
ポインタと関数
ポインタと配列
第10章 ポインタ
3



すべての変数は、メモリ上にその分の領域とい
うものが確保されている
そのメモリ上の位置、番地のことをアドレスと
いう
ある変数のアドレスは、その変数名に『&』を
付け加えたもので、たとえば、変数a のアドレ
スは『&a』と表される
第10章 ポインタ
4

このアドレスを代入できる特殊な変数をポイン
タという

宣言

初期化
int *p;
p = &a;
代入時は『*』がいらないので注意
第10章 ポインタ
5

また以下のようにポインタ変数に『*』をつけ
ると、ポインタに入っているアドレスの指す変
数と同じ扱いになる
色々省略
int a = 25;
int *p;
宣言時の『*』とは別個に
p = &a;
思って
*p = 50;
printf(“%d\n”, a);

つまり *p = a
第10章 ポインタ
6

ここでひとつ実行してみよう
#include <stdio.h>
int main(){
int a = 25;
int *p = &a;
printf(“%d\n”,
printf(“%d\n”,
*p = 50;
printf(“%d\n”,
printf(“%d\n”,
return 0;
}
a);
*p);
*p);
a);
第10章 ポインタ
7


実行結果
このように『*p』など『*』などをつけてアド
レス先の変数と同じ扱いになることを
間接参照というよ
用語は好きに覚えてね
第10章 ポインタ
8

以下のコードを必ず使って、入力した数値を間
接参照で表示し、値を10倍して今度は元の変数
で表示をやってみよう
printf(“a > %d\n”, *p);
printf(“a × 10 = %d\n”, num);

実行例はこちら
第10章 ポインタ
9

ちょっと #include <stdio.h>
まわりく int main(){
int num;
どいかな
int *p;
printf("値を入力してください > ");
scanf("%d", &num);
p = &num;
printf("num > %d\n", *p);
*p *= 10;
printf("num × 10 = %d\n", num);
return 0;
}
第10章 ポインタ
10

以下のプログラムは sub 関数で変数a の値を変
更しているが、うまくいっていない
#include <stdio.h>
void sub(int a){
a = 100;
}
int main(){
int a = 0;
sub(a);
printf(“%d\n”, a);
return 0;
}
第10章 ポインタ
11



関数に渡した値は、関数内の変数にコピーされ、
使用されている
つまりその変数はローカル変数(そういやそんな
のあった)なので、値を変更しても、関数の外ま
でそれが適用されない
ゆえに、前ページのプログラムの値は変わらな
い
第10章 ポインタ
12

今度は関数にアドレスを渡してみる
#include <stdio.h>
void sub(int *p){
*p = 100;
}
int main(){
int a = 0;
sub(&a);
printf(“%d\n”, a);
return 0;
}
第10章 ポインタ
13


ポインタに『*』をつけたものは、そのアドレ
スが指す変数と同じに扱う(2度目)
この場合、アドレスを経由して変数の値をい
じったため、関数の外においても変更が適用さ
れているよ
第10章 ポインタ
14
半径を入力して、そこから円の円周と面積を求
める calc 関数を作ってみよう
 その時必ず以下の main 関数を用いてね

int main(){
double a, b, c;
printf(“半径は > ”);
scanf(“%lf”, &a);
calc(a, &b, &c);
printf(“円周は > %f\n”, b);
printf(“面積は > %f\n”, c);
return 0;
}
円周率は 3.14 で
第10章 ポインタ
15

『*』ば #include <stdio.h>
かりで void calc(double a,double *b, double *c){
*b = a * 2 * 3.14;
すね
*c = a * a * 3.14;
}
int main(){
double a, b, c;
printf(“半径は > ”); scanf("%lf", &a);
calc(a,&b,&c);
printf("円周は > %f\n",b);
printf("面積は > %f\n",c);
return 0;
}
第10章 ポインタ
16

配列のアドレス
たとえば
int num[5];
という配列をつくったとして、それぞれの変数のアドレ
スは
&num[0], &num[1], &num[2], ………
となるのはイメージしやすいと思うけど、実は配列名で
ある num も &num[0] と同じく num[0] のアドレス
を表している
第10章 ポインタ
17
配列名 num が &num[0] と表すとき、
num+1 は &num[1]、num+2 は &num[2]…
を表すことになる



つまり
⇒
*num == num[0]
*(num+1) == num[1]
*(num+2) == num[2]
ちなみに『*p』も『*(p+1)』『*(p+2)』…と
していくことで、隣の領域にある変数の値を示
していくことができる
第10章 ポインタ
18

これで関数に配列を渡すやり方が説明できる!
#include <stdio.h>
void clear(int *p){
実行してみよう!
for(int i=0; i < 5; i++){
*(p + i) = 0;
}
}
int main(){
int num[5] = {98, 102, 5, 77, 236};
clear(num);
for(int i=0; i < 5; i++){
printf(“%d\n”, num[i]);
}
return 0;
}
第10章 ポインタ
19



実行結果
clear 関数に配列名 num を引数として渡し、そ
れをポインタで受け取る
関数内の処理で『*p』『*(p+1)』『*(p+2)』
…としていくことで『*num[0]』
『*num[1]』『*num[2]』…と同じことをし
ているよ
第10章 ポインタ
20




変数のアドレスを格納できるポインタ変数
ポインタに『*』をつけることでアドレス先の
変数と同じ扱いができる
配列名は配列の先頭の変数のアドレスと同じ
配列を関数に渡す時、ポインタとして受けるこ
とができる
ややこしいのでまとめてみました
第10章 ポインタ
21
ヒント:文字列は『\0』
で必ず終わるよ

文字列を入力させて、その長さを算出する
strlen 関数を使ったプログラムを作ってみよう
main 関数はこんなカンジ
int main(){
char words[128];
int num = 0;
printf("文字列を入力してみよう > ");
scanf("%s", words);
num = strlen(words);
printf("文字列の長さは %d です\n", num);
return 0;
}
第10章 ポインタ
22
#include <stdio.h>
int strlen(char *p){
int n = 0;
while(*p != '\0'){
p++;
// このカタチでもポインタをずらせる
n++;
}
return n;
}
int main(){
char words[128];
// ちゃんと十分に配列を確保しよう!
int num = 0;
printf(“文字列を入力してみよう > ”); scanf("%s", words);
num = strlen(words);
printf("文字列の長さは %d です\n", num);
return 0;
}
第10章 ポインタ
23

変数をまとめて宣言する方法

ヘッダーファイルを自分で作る
プログラミングで便利な構造体のはなし
第10章 ポインタ
24

テンプレ
第10章 ポインタ
25