「C言語/関数」の版間の差分

削除された内容 追加された内容
フリースタンディングなど難解な話題を、『C言語/中級者向けの話題』に移動した。こちらからは除去。
static変数について勘違いしてたので修正。長いのでいったん投稿。
127 行
== static 変数とポインタの必要性 ==
このように、C言語の(ユーザーが自分で定義する)「関数」は、かなり特殊なシステムである。
 
 
<source lang=c>
// static変数の使用例
#include <stdio.h>
#include <stdlib.h> // 「続行するには何かキーを押してください . . .」を表示するのに必要。
 
void kansuu(void) {
int b = 0;
static int c = 0;
b = b + 1;
c = c + 1;
 
printf("b = %d ,c = %d \n\n" , b,c);
}
 
int main(void) {
kansuu();
kansuu();
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
 
return 0;
}
</source>
 
;実行結果
b = 1 ,c = 1
b = 1 ,c = 2
続行するには何かキーを押してください . . .
のようになる。
 
このように、static宣言された変数(上の例ではc)は、その関数が終わっても、数値が保存される。
 
また、初期化がされる(cに0が代入される)のは、最初に呼び出された1回だけである。
 
 
 
なお、下記のように書くと、エラーになる
<source lang=c>
// static宣言でエラーになる例
#include <stdio.h>
#include <stdlib.h> // 「続行するには何かキーを押してください . . .」を表示するのに必要。
 
void kansuu(void) {
int b = 0;
static int c = 0;
b = b + 1;
c = c + 1;
}
 
int main(void) {
 
kansuu();
printf("b = %d ,c = %d \n\n" , b, c); // このprintf関数がstatic宣言されたcにアクセスできない
 
kansuu();
printf("b = %d ,c = %d \n\n" , b, c); // このprintf関数がstatic宣言されたcにアクセスできない
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
 
return 0;
}
</source>
 
 
このように、static変数は、呼び出し元の関数は、存在を感知できない仕組みである。これによって、バグ発生時に原因箇所を特定しやすくしている。
 
 
また、以下のコードも、エラーになる。
 
<source lang=c>
// static宣言でエラーになる例2
#include <stdio.h>
#include <stdlib.h> // 「続行するには何かキーを押してください . . .」を表示するのに必要。
 
void kansuu(void) {
b = b + 1; // ここでエラー発生。bが何かを判断できない
c = c + 1;
}
 
int main(void) {
int b = 0;
static int c = 0;
 
kansuu();
printf("b = %d ,c = %d \n\n", b, c); // このprintf関数がstatic宣言されたcにアクセスできない
 
kansuu();
printf("b = %d ,c = %d \n\n", b, c); // このprintf関数がstatic宣言されたcにアクセスできない
 
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
 
return 0;
}
</source>
 
コンパイルの仕組みでは、上から順に部品を組み立てていくような仕組みなので、コード上方にある関数はコード下方にある関数の内容を知らない。
 
 
たとえ、コード下にある関数がmain関数であっても、その内容を知らないのである。よって、上記のようなコードはコンパイルエラーになる。
 
かといって、<code>kansuu)<code>をmain関数よりも下に書くと、今度はmain関数が、kansuuの内容を感知できないのである。
 
main関数といえども、main関数ブロックよりも下に書かれた内容を知ることはできない。
 
なので通常、main関数は一番下に書かれる。
 
 
 
 
実用では、子サイド(呼び出し先)の関数で、親サイド(呼び出しもと)の変数の値も変更したい場合も多く、その場合には、「 static 変数」(静的変数)もしくは「ポインタ」という機能をつかう。