C言語講座 第4回 ポインタ
変数のメモリ上のアドレスを格納するもの。 ポインタとは 変数のメモリ上のアドレスを格納するもの。 アドレスって? 【名詞】address : 住所, あて名, 所番地 メモリ上の場所のこと。
ポインタの使い方・書き方 #include <stdio.h> int main(){ } int a=3; int* pa; pa=&a; printf("aの値は %d \n",a); printf("aのアドレス(pa)は %d \n\n",pa); return 0; }
ポインタの使い方・書き方 int* ポインタ変数名 int型のポインタ変数の宣 言 &変数名 変数のアドレスを表す int型の変数aのアドレスをポインタ変数へ int* pa; ←int型のポインタ変数paを作成 pa = &a; ←paにaのアドレスを入れる int* ポインタ変数名 int型のポインタ変数の宣 言 &変数名 変数のアドレスを表す & : アドレス演算子
scanfについて 今まで使ってきたscanf関数でも・・・ とりあえずつけてきたこの&はaのアドレスを渡していた int a; scanf(“%d” ,&a ); とりあえずつけてきたこの&はaのアドレスを渡していた scanf関数は “アドレスが示す場所” を入力された値に 書き換える
*の使い方 printf("paが指しているものの中身は %d \n",*pa); さっき書いたプログラムに を付け足してください ここで出てくる *pa はpaの指す場所の中身を見ています ここでは中身は3でした
*の使い方 ・・・ a pa メモリ ↓aのアドレスを持っている paの中に入っている アドレス先(a)を見る printf("paが指しているものの中身は %d \n",*pa); ・・・ a pa
*の使い方 次に *pa = 7; printf("paが指しているものの中身は %d \n\n“, a); を追加すると
*の使い方 つまり、 *ポインタ変数 ポインタ変数の先の中身を表す ポインタ変数を使うことで間接的に値を変えることができ る! *ポインタ変数 ポインタ変数の先の中身を表す ポインタ変数を使うことで間接的に値を変えることができ る! この機能はC言語においてとても重要なのでマスターし ておきましょう 1年後期のC++でも出てきます
なぜポインタを使うのか aの値を変えたいのであれば直接変えればいいので は?と思うかもしれません 確かに今までのような使い方では直接書き換えれば事 足りてしまいます 必要になる時というのは関数へ“アドレス渡し”する時で す
ポインタと関数 //日付を変えるプログラム set_day(month, date); #include <stdio.h> return 0; void set_day(int m, int d); } int main(){ void set_day(int m, int d){ int month=1; printf("日付をセットします\n"); int date=1; m=5; d=27; printf("%d月%d日\n",month,date);
ポインタと関数 結果 変わらず・・・ なぜか 関数には変数の中身しか渡っていないから (ここでは1という数字のみ) ではどうするか
ポインタと関数 //日付を変えるプログラムそのに set_day(&month, &date); //赤字のところが変化した場所 #include <stdio.h> return 0; void set_day(int* m, int* d); } int main(){ void set_day(int* m, int* d){ int month=1; printf("日付をセットします\n"); int date=1; *m=5; *d=27; printf("%d月%d日\n",month,date);
ポインタと関数 結果 変わった! 今度は関数の引数をアドレスに変えたので関数内で変 更することができた
ポインタと関数 void set_day(int* m, int* d) set_day(&month, &date); ↑関数の宣言部 引数がポインタ変数になっている つまり、アドレスを受け取る set_day(&month, &date); ↑main文内の関数呼び出し文 &変数名 で変数のアドレスを表している つまり、変数のアドレスを送っている
ポインタまとめ int* ポインタ変数名 int型のポインタ変数の宣言 &変数名 変数のアドレスを表す &変数名 変数のアドレスを表す *ポインタ変数名 ポインタ変数の先の中身を表す 直接いじることのできないところ(関数とか)では、ポ インタを使うことで扱うことができる ポインタを使うことでより動作の軽いプログラムを作るこ とができる
演習問題1 int型変数 a, bをscanf関数を用いて入力し、自 作関数swap()を作成して値a、bを交換して表 示せよ。
演習問題1 解答例 #include<stdio.h> void swap(int *x,int *y){ int tmp; 演習問題1 解答例 #include<stdio.h> void swap(int *x,int *y){ int tmp; printf(“入れ替えま す!”); tmp=*x; *x=*y; *y=tmp; } int main(void){ int a,b; printf(“a=”); scanf_s(“%d”,&a); printf(“b=”); scanf_s(“%d”,&b); printf(“a=%d,b=%d\n”,a,b); swap(&a,&b); return 0; }
演習問題1 実行結果
演習問題2 1から任意の数までを出力し、3の倍数ならFizz, 5の倍数 ならBuzzと出力するようなプログラムを書け for文とwhile文の両方でかけるとなお良い ポインタは今回関係無いです
演習問題2 解答例(for文 ver ) #include <stdio.h> printf("%d",i); if(0==i%3) int main(){ printf("Fizz"); int i,n; if(0==i%5) printf("Buzz"); printf("整数を入力してくだ さい>"); printf("\n"); } scanf("%d",&n); return 0; for(i=1;i<=n;i++){ if(0!=i%3 && 0!=i%5)
演習問題2 解答例(while文 ver ) #include <stdio.h> printf("%d",i); if(0==i%3) int main(){ printf("Fizz"); int n,i=1; if(0==i%5) printf("Buzz"); printf("整数を入力してくだ さい>"); printf("\n"); i++; scanf("%d",&n); } return 0; while(0<i && i<=n){ if(0!=i%3 && 0!=i%5)
演習問題2 実行結果
お疲れ様でした~