ポインタ変数を学習していると,なんだか面倒で,できれば使いたくないと思われるかもしれない.
しかし,Cのプログラムにおいて,以下のようなポインタ変数の使用が必須,またはポインタ変数を使用することが望ましい場面がある.
scanf, strcpy, strcat, strlen, fscanf
など)fopen, malloc, calloc
など)
特に,計算機の性能を最大限発揮したい場面や,ハードウエアに密接に関わる制御プログラムや,計算機システムの根幹にかかわるプログラムを書く場面では,C言語が大いに活躍している.
(逆に,機械学習や情報数理,Webなどの分野では,データ処理やアルゴリズム実装のウエイトが高いため,pythonやJavaScriptなど,特定分野の関連ライブラリが充実している言語が選択・使われることが多い.)
ポインタ変数は,他の変数などを指している状態で使うのが原則なので,指す相手(=アドレス値)が定まっていないポインタを参照したり,代入などをしてはいけない.
もちろん,NULL
ポインタが指しているアドレスに代入することも禁止である.
#include <stdio.h>
int main(void)
{
int *p; // これだけでは何もさしていない!
// int *p = NULL; // NULLポインタ
*p = 100; // OMG !! どこに代入される?
return 0;
}
タチの悪いことに,このコードはコンパイルも通るし,実行しても問題が起きない場合も多い.
このような迷子のポインタを使うことはプログラムの深刻なバグになるので,ポインタ変数は慎重に扱う必要がある.
(意図的にポインタでエラーを起こす場面は通常無いが,うっかり無効なポインタ参照をしてしまうことがよくある.)
#include <stdio.h>
int main(void)
{
int data;
int *p = &data;
*p = 100; // pはdataを指しているので,OK
return 0;
}
上記プログラムを実行して,どのようになるか(コンパイルエラー,実行時エラーなど)を確かめよ.
関数に引数を渡す方には,3種類あることは関数の回に述べたが,再度確認してみよう.
引数の渡し方
*, &
の記述を減らせるメリットがある.&
を明示して渡すので,変更される可能性があるとわかる.)