ポインタとは
1.目的
- ポインタについて理解する。
- ポインタの使い方について理解する。
目次
2.ポインタとは
・アドレスを格納する変数のこと。
・取得したアドレスにデータの読み書きを行うことができる。
ポインタのメリット
・できることが増える。
・高速化が出来る。
・省メモリ化出来る。
・引き渡した変数の値を変更できる。
アドレスについて:
・
参考:【C言語】ポインタを初心者向けに分かりやすく解説 | だえうホームページ
3.使い方
型 変数; //アドレスを参照する変数 //ポインタの宣言 型 *ポインタ変数; //ポインタの使用 ポインタ変数 = &変数; //変数のアドレスをポインタ変数に格納 //ポインタに数値を入力 *ポインタ変数 = 数値;
4.プログラムの作成(ポインタの宣言と入力)
#include <stdio.h> int main(void){ // Your code here! //変数宣言 int x; //通常の変数 int *ptr; //ポインタ変数 //変数への入力 x = 10; //x:Aの値を入れる ptr = &x; //ptr:xのアドレスの値を入れる //出力確認 printf("x=%d\n",x); //変数xの値出力 printf("ptr=%d\n", *ptr); //指定されているアドレスに格納されている値を表示 //ポインタ変数に入力 *ptr = 20; //出力確認 printf("x=%d\n",x); //変数xの値出力 printf("ptr=%d\n", *ptr); //指定されているアドレスに格納されている値を表示 }
結果:https://paiza.io/projects/10XhwaAA1F_mTKKWKCaQlA?language=c
プログラム説明
・ポインタ変数ptrが、xのアドレスを指定する。
・ptrが指しているアドレスに格納されているデータの値を20に変更。
・変数xの値と、ptrが指すアドレスに格納されているデータを出力した。
5. プログラムの作成(関数にポインタで渡す:参照渡し)
#include <stdio.h> void funcA(int b) { b = 10; } void funcB(int *b) { (*b) = 200; } int main() { int a = 1; printf("a=%d\n", a); funcA(a); printf("funcA()の結果 : a=%d\n", a); funcB(&a); printf("funcB()の結果 : a=%d\n", a); return 0; }
実行結果:https://paiza.io/projects/0llplWenErAnXSQYZLG6pA?language=c
プログラム説明
・変数aを宣言
・変数aを通常の変数として、引数にした場合と
変数aをポインタ変数として、引数にした場合を比較する。
・変数aをポインタ変数として、引数にした場合、関数で引数の値を
変更すると、関数の呼び出し元の変数も、その値に変更される。
参照渡しの使いどころ
C言語を学び始めだと、参照渡しを使い所が分からなかったりする。
実際にどういう場合に使うかというと、
ループ分などで、関数を使用した時に、変数の値を保持したい時がある。
そんな時に使えるのが参照渡しだ。
6. プログラムの作成(参照渡しとループ)
/* 参照渡しをした場合と、通常の変数で渡した場合の ループによる関数のふるまいの違いを確認する。 */ //ヘッダのインクルード #include <stdio.h> void func1(int set); void func2(int *set); int main(void){ //変数宣言 int set1=0; //func1関数へ渡すための変数 int set2=0; //func2関数へ渡すための変数 int i = 0; //ループカウント用変数 //ループ開始 while(1){ i += 1; //カウント+1 printf("ループ%d回目\n",i); //関数の実行 func1(set1); //func1実行:set1を変数で渡す。 func2(&set2); //func2実行:set2をポインタで渡す if(i==3)break; //ループ3回で抜ける。 } } //変数set1を受け取り、+1して表示する関数 void func1(int set){ set += 1; printf("func1=%d\n",set); } //変数set2をポインタで受け取り、+1して表示する関数 void func2(int *set){ (*set) += 1; printf("func2=%d\n",*set); }
実行結果:https://paiza.io/projects/38w03tLG4TS3Pc87MGjfvw?language=c
※この実行結果のように、参照渡しで渡さなければ、変数の値が保持されない。
組み込みなどで、スイッチが押されたら関数を実行する場合などによく使う。
7.プログラムの作成(ポインタでアドレスを指定しない場合のエラー)
#include <stdio.h> int main(){ char *ptr; //ポインタの宣言 printf("*ptr = %c\n", *ptr); //ポインタに格納されている数値の表示 }
結果:https://paiza.io/projects/11s0zU8RtZl6l9ynYsP3Kw?language=c
・ポインタの先が指定されていない状態で、使用しようとすると、エラーとなる。
対処法
#include <stdio.h> int main(){ char *ptr; //ポインタの宣言 ptr = NULL; //ポインタの先をNULLにする。 printf("*ptr = %c\n", *ptr); //ポインタに格納されている数値の表示 }
結果:https://paiza.io/projects/LSuMs0QzdGprF_kjtKrymg?language=c
・NULLを使用する。
・NULL を指すことで、そのポインタがどこも指していない状態を明示的に表す。
・NULLにより、ポインタが意図しないアドレスにアクセスすることを防止する。
参考:【C言語】「NULL」の意味とNULLを用いた「安全なポインタの使い方」 | だえうホームページ
関連記事
C言語:
・組み込みの為のC言語基礎知識1(printf) - Project_OKI’s diary
・C言語基礎知識2(for分で処理を繰り返す) - Project_OKI’s diary
・C言語基礎知識3(配列) - Project_OKI’s diary
・知らないと損するお金の話(ふるさと納税、確定申告とワンストップ納税どっちが得?) - Project_OKI’s diary
・C言語基礎知識6(関数) - Project_OKI’s diary
・C言語基礎知識7(構造体1) - Project_OKI’s diary
・C言語基礎知識8(enum:列挙型) - Project_OKI’s diary
・C言語基礎知識9(typedef) - Project_OKI’s diary
・C言語基礎知識10(extern宣言) - Project_OKI’s diary
・C言語基礎知識11(#define) - Project_OKI’s diary