C言語の文法入門(3)

今回は関数について学ぶ

関数

宣言

戻り値の型 関数名(引数の型 引数の名前){
   処理;
  ...
   return 戻り値;
}

C言語ではdeffunctionといった関数を宣言する専用の文はなく、変数を宣言するのと同じように記述する。 基本的に関数を呼んだ時に戻り値があることを前提としているので、オブジェクト指向というよりも関数型に近い気がする。 もちろん戻り値がない関数を作ることもでき、その場合voidを使う。 このvoidは引数がないときにも使用され、戻り値も引数もない関数は以下のように宣言する。

void function(void){
  printf("Hello World");
}

ちなみにHello Worldのコードで記述したint main(){}という文も関数で、 main関数はプログラム実行時に実行され、記述されていないとコンパイル時にエラーが発生する。 main関数の宣言の仕方にもルールが有り、

int main(void) {}
int main(int argc, char *argv[]) {}
int main(int argc, char **argv) {}

このどれかの書き方で宣言するのが正しい方法とのこと。 つまりHello Worldのコードでは間違いですね。修正しておきます 汗

呼び出し

宣言した関数の呼び出しは以下のように行う。

関数名(引数);

プロトタイプ宣言

関数を呼び出すためには呼び出す前に関数を記述していなければならない というルールが有り、そのルールの抜け道として利用できるのがこの文だ。 プロトタイプ宣言の方法は以下の通り

戻り値の型 関数名(引数の型);

処理と引数の名前部分は記入せず、それ以外を宣言しておく。 処理の記述をするときは、通常通りに

戻り値の型 関数名(引数の型 引数の名前){
   処理;
  ...
   return 戻り値;
}

と記述すればOK

スコープについて

関数の中で宣言された変数はローカル変数と呼ばれ、その関数の中でしか呼ばれない。 試しにmainの中で変数を宣言して、mainの中で呼ぶ別の関数の中で呼び出そうとしてみる。

#include <stdio.h>
void test(void){
  printf("inside test, i = %d\n", i);
}
int main(void){
  int i = 1;
  printf("i = %d", i);
  test();
  return 0;
}

コンパイルすると

> error: use of undeclared identifier 'i'

と出てコンパイルすることができなかった。

そこで登場するのがglobal変数だ 関数の外で変数を宣言すると、そのファイルのどの場所からもアクセスすることができる

#include <stdio.h>
int i = 1;
void test(void){
  printf("inside test, i = %d\n", i);
}
int main(void){
  printf("i = %d/n", i);
  i++;
  test();
  return 0;
}

出力結果

i = 1
inside test, i = 2

似たような話題で、static変数というものもある

static 変数の型 変数の名前;

というふうに宣言する。 この変数は、 同じ関数を何度も呼び出し、前回呼び出された時に宣言した変数の中身を利用したい という時に使用する。 static変数を使用した例

#include <stdio.h>
void test(void){
  static int i = 1;  #最初に呼ばれたときのみ実行する
  printf("i = %d\n", i);
  i++;
  }
int main(void){
  for(a = 0; a <5; a++){
    test();
  }
  return 0;
}

出力結果

i = 1
i = 2
i = 3
i = 4
i = 5