質問: 最近、C言語を学習し始めた者です。 以下のソースコードを実行したところ、エラーが発生しました。 エラーの原因が知りたいです。基礎的な質問だと思いますがよろしくお願いします。 ### 該当のソースコード ``` #include void func(int *p,int i); int main(void){ int *p,i; func(p,i); printf("%d\n",*p); return 0; } void func(int *p,int i){ i=100; p=&i; return; } ``` ### 発生している問題・エラーメッセージ ``` Segmentation fault (コアダンプ) ```
回答: C言語では、引数はすべて**値渡し**です(構造体引数すら、コピーして値渡しという挙動になります)。つまり、`func`の中で代入した変数は、`main`の中の変数とは別なので、呼び出した`main`の側に影響することはありません。 そして、`main`内での`int *p`は初期化されないままなので、それを逆参照した結果は「未定義」です。つまり、「コンパイルに失敗する」「何事もなかったかのようにどこかわからない場所を参照する」「コアダンプする」「システムごとクラッシュする」など、**何が起きるともしれない**プログラム、ということです。 関数から外側に値を伝える方法は3つあります。 1. 返り値を返す 2. 外部変数(グローバル or ファイル単位の`static`)を書き換える 3. ポインタで受け取って、そのポインタ経由で書き込む(ポインタ自体を書き換えたいなら、`int **`のようにダブルポインタとする必要があります)