とある科学の備忘録

とある科学の備忘録

CやPythonのプログラミング、Arduino等を使った電子工作をメインに書いています。また、木製CNCやドローンの自作製作記も更新中です。たまに機械学習とかもやってます。

【C言語】NO.12 #define と #include

いままで多くのプログラムを書いてきましたが、だれもが一度は、

#include

#define

という単語を見たことがあるはずです。今日は、この2つについてブログを書いてみました。

1. #includeの使い方

includeは、複数のファイルを統合するための命令です。

いままで、多くのプログラムを書いてきましたが、どれも1つのソースファイルの中で書いてきました。これを複数のファイルに分割して書きたくないですか? *1

しかし、ただ複数のファイルに書いただけでは、プログラムを実行しようとしてもエラーが出てしまいます。これは、ファイル同士の関連付けができていないためです。

Functions.cpp

int tasizan(int, int);
int tasizan(int a, int b){
  return a+b;
}

main.cpp

  int main(){
  int a =20;
  int b = 30;
  int c;
  c = tasizan(a + b);
  printf("aプラスbは%dです", c);
  return 0;
}

この二つのソースファイルを実行しようとすると、まず、main.cpp の main()関数が呼び出されます。その後、

  c = tasizan(a + b);

で、Functions.cpp の中の tasizan() 関数が呼び出されることを期待して作ったものです。

ですが、実際は、コンパイラが Functions.cppを認識していないため、tasizan()関数が読み込めず、エラーが出てしまいます。

この状況を克服するには、#include 構文をマスターする必要があります。

(1)#include構文の使い方

プログラムの文頭に

#include " ソースファイル名"

という風に書くと、そのソースファイルをビルドに含めることができます 。上の例で行くと

#include "Functions.cpp"

とmain.cppの文頭に書くことで、Functions.cppの中の変数や関数がすべて、コンパイラに認識されます。なので、正しく実行ができるようになるのです。

コラム

プログラムの文頭で

include <stdio.h>

という一文を見たことがありますよね。この命令も、「パソコンに元から搭載されている「stdio.h」というファイルがどこかにあり、それをこのプログラムを実行するときに読み込んでください」という意味です。

ほかにも、

#include <math.h>

などがありますが、これらも同様です。

ところで、

#include "ファイル名"  

と、
>|cpp|
#include <ファイル名>
|

にも違いがあり、

  • #include "ファイル名" は、自分で作ったファイルを読み込むとき
  • #include <ファイル名> は、PC上に元から用意されたファイルを読み込むとき

です。


2.#define構文

define構文は単語や、変数名、関数名を置き換えます。
書き方は、主語のない第5文型です。「define O C」で「OをCと定義する」です。*2

例えば、

#define FIVE 5

int main(){
  int a;
  a = FIVE
  printf("%d", a);
  return 0;
}

とすると、

5

と表示されます。

この場合、#define 命令は、プログラムを実行するときに、「FIVE」を「5」という定数に書き換えて、実行しています。


(2)#define構文の性質

  • 一度 #deine で定義すると、同じ文字は使えない

例:

#define FIVE 5  //FIVEを5に定義する
#define FIVE 4  //FIVEが二回定義されたので、エラーになる
  • #define は文頭に書く

関数の中などに書いてもいいのか...?(←後で調べます)


(3)#defineを使うときに注意すること

defineは、プログラムを実行するときに、命令をそのまま置き換えます。なので、次のようなプログラムを書くと、予期しない動作をしてしまいます。

#define TASHIZAN(x, y) x + y
int a = 2;
int b = 3;
int c = TASHIZAN(a, b);
int d = 3*TASHIZAN(a, b);

この場合、変数cと変数dがどのように計算されるのかというと、
変数cの計算のされ方:

int c = TASHIZAN(2,3)

  ↓実行時に#define命令が発動される

int c = 3+2

↓計算

int c = 5


変数dの計算のされ方

int d = 3 * TASHIZAN(2, 3)

  ↓#define命令が発動

int d= 3 * 3 + 2

  ↓足し算よりも掛け算のほうが優先されるので...

int d = 11

となってしまいます。プログラム作成者は、

int d = 3 * (3+2) 

   ↓

int d = 15;

となることを予想して作っていますが、#define命令は、そのまま置き換えられるため、予想道理にはいかないのです。

この場合、解決策は、一行目を

#define TASHIZAN(x, y) (x + y)

とすると、期待通りの動作をしてくれます。

*1:共同作業するときには、モジュールごとにソースファイルを分けて、あとからそれらを統合する、という手段をとることができます。

*2:実際の英語でdefine(動詞::定義する)がどのような使われ方をしているかはわかりません。あくまでプログラムの中の世界です