キーワード

ANSI C 標準では 32 のキーワード(予約語?)が規定されている。

auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while

また、よく使われる拡張キーワードには次のものがある。

asm _cs _ds _es
_ss cdecl far huge
interrupt near pascal

すべて小文字。キーワードは関数名や変数名には使えない。
なんか意味の想像できないのもあるけど、それはそのうち。

関数の戻り値

関数から戻り値を返すには return を使う。

return 値;

戻り値の値は関数定義の戻り値と同じじゃなければならない。戻り値が vold の場合は、単に return と書ける。

関数の途中で return に出会うと、そこで(戻り値を伴って)呼び出し元に制御が戻る。以降に記述があっても実行されない。

呼び出し側で戻り値を使うには、変数に代入すればいい。または、printf などの関数の引数としてそのまま使うこともできる。

#include

int square(int n);

int main(void)
{
    int i;
    int answer;

    printf("Input? ");
    scanf("%d", &i);

    answer = square(i);
    printf("Square is %d\n", answer);
}

int square(int n)
{
    return n * n;
}

実行結果:

takatoh@nightschool $ ./sample_1_8
Input? 5
Square is 25

関数の定義

関数の定義は、一般的には次の形式をしている。

戻り値の型 関数名(引数リスト)
{
    文;
    ....
    return 戻り値;
}

基本的には main 関数と同じだ。戻り値がない場合は void を指定する。また、引数がない場合にも vold と書いておく。戻り値は return で返す。

main 関数と違うのは、関数プロトタイプの宣言が必要だということ。関数プロトタイプは次のような形式をしている。

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

これを実際に関数を定義する前に書いておく(普通はファイルのはじめのほう)。

#include

void func1(void); // prototype of func1()

int main(void)
{
    printf("I like ");
    func1();
    printf(".\n");
}

void func1(void)
{
    printf("C");
}

実行結果:

takatoh@nightschool $ ./sample_1_7
I like C.

ところで、関数プロトタイプを書かないとどうなるだろう。上のプログラムの関数プロトタイプをコメントアウトしてコンパイルしてみると:

takatoh@nightschool $ gcc sample_1_7a.c -o sample_1_7a
sample_1_7a.c:13:6: warning: conflicting types for ‘func1’ [enabled by default]
 void func1(void)
      ^
sample_1_7a.c:9:5: note: previous implicit declaration of ‘func1’ was here
     func1();
     ^

何やらよくわからないけど、エラーになるってことはわかった。

コメント

コメントは /* と */ で囲む。
また、ANSI 標準ではないけど一行コメント // も使えるコンパイラも多いようだ。gcc で使えるか試してみよう。

#include

int main(void)
{
    printf("alpha\n");
    /* printf("bravo\n"); */
    printf("charlie\n");
    // printf("delta\n");
    printf("echo\n");
}

実行結果:

takatoh@nightschool $ ./sample_1_6
alpha
charlie
echo

お、/* */ だけじゃなくて一行コメントも使えてるな。

算術演算子

+ – * / % の5つがある。* / % は + – よりも優先度が高い。
% は剰余を計算するものなので整数型にしか使えない。

#include

int main(void)
{
    printf("%d\n", 2 + 3);
    printf("%d\n", 2 - 3);
    printf("%f\n", 2.0 * 3.0);
    printf("%f\n", 5.0 / 2.0);
    printf("%d\n", 5 / 2);
    printf("%d\n", 5 % 2);

    return 0;
}

実行結果:

takatoh@nightschool $ gcc sample_1_5.c -o sample_1_5
takatoh@nightschool $ ./sample_1_5
5
-1
6.000000
2.500000
2
1

整数の除算の余りは切り捨てられるってことでいいのかな。

プログラムに数値を入力する

scanf 関数でキーボードからの入力を受け取ることができる。一般的な書式は次の通り。

scanf("%d", &int型変数名);

浮動小数点数を受け取るには、1つ目の引数を “%f” にする。変数名の前に付いているアンパサンド(&)はポインタと関係してるはずだけどとりあえずはスルー。

サンプルプログラム。

#include

int main(void)
{
    int n;
    float f;

    printf("Input integer: ");
    scanf("%d", &n);

    printf("Input float: ");
    scanf("%f", &f);

    printf("%d\n", n);
    printf("%f\n", f);

    return 0;
}
takatoh@nightschool $ gcc sample_1_4.c -o sample_1_4
takatoh@nightschool $ ./sample_1_4
Input integer: 3
Input float: 2.5
3
2.500000

変数の宣言と値の代入

C は静的な型付け言語で、変数を利用するには予め宣言しておかないといけない。変数の宣言はこうする。

型 変数名, 変数名;

同じ型ならカンマで区切って複数の変数を宣言できる。
変数のスコープは、その宣言する場所によって決まる。関数の中で宣言した変数は関数の中だけで有効なローカル変数、関数の外で宣言すればグローバル変数になる。

C には 5つの基本的な型がある。

キーワード
文字char
符号付き整数int
浮動小数点数float
倍精度浮動小数点数double
値なしvoid

変数への値の代入は = を使う。ココらへんは他の言語と一緒。

じゃ、サンプルプログラムを書いてみよう。

#include

int main(void)
{
    int num;

    num = 100;
    printf("Value is %d\n", num);

    return 0;
}

実行結果:

takatoh@nightschool $ gcc sample_1_3.c -o sample_1_3
takatoh@nightschool $ ./sample_1_3
Value is 100

C言語はじめました

このあいだ Qt について書いたせいか、C/C++ を勉強してみたくなった。Qt は C++ が標準なんだけど、まずは C からはじめることにした。で、書庫から昔買った本を引っ張り出してきた。

[amazonjs asin=”4798115770″ local=”JP”]

ちょっと古い本だけどまあいいだろう。

早速、短いプログラムが出てきたので書いてみよう(本とはちょっと変えてある)。ファイルの拡張子は .c だ。

#include

int main(vold)
{
    printf("This is short C program.");
    return 0;
}

#include はヘッダファイルを読み込むための、プリプロセッサのディレクティブで、ここでは stdio.h というヘッダファイルを読み込むことをコンパイラに指示している。stdio.h には標準的な関数に関する情報が書かれている。この例では printf 関数を使うために読み込んでいる。

int main(void) は main 関数の定義の最初の部分。main が関数名で、() の中が引数のリスト。void というのは引数をとらないことを示している。int は関数の戻り値の型を指定している。
続く中括弧 {} の中が関数の本体。2つの文があって、printf 関数の呼び出しと return で戻り値 0 を指定している。文はセミコロンで終わらないといけない。

さて、じゃあこれをコンパイルしてみよう。

takatoh@nightschool $ gcc sample_1_1.c
takatoh@nightschool $ ls
a.out  sample_1_1.c

a.out というファイルが新しく出来た。これがコンパイルした結果の実行ファイルだ。実行ファイルの名前を指定するには -o オプションを使う。省略すると a.out という名前になるらしい。

takatoh@nightschool $ gcc sample_1_1.c -o sample_1_1
takatoh@nightschool $ ls
a.out  sample_1_1  sample_1_1.c

今度は sample_1_1 ファイルが出来た。これを実行してみよう。

takatoh@nightschool $ ./sample_1_1
This is short C program.takatoh@nightschool $

printf が自動では改行してくれないせいで、プロンプトが続けて表示されてしまっているけど、うまく動いてるようだ。

サンプルをもうひとつ。

#include

int main(vold)
{
    printf("This is ");
    printf("another ");
    printf("C program.\n");
    return 0;
}

文が増えた。基本的に、文は上から順に実行される。だからこのプログラムは “This is another C program.” と出力するはずだ。ついでに最後には改行を入れてみた。

takatoh@nightschool $ gcc sample_1_2.c -o sample_1_2
takatoh@nightschool $ ls
a.out  sample_1_1  sample_1_1.c  sample_1_2  sample_1_2.c
takatoh@nightschool $ ./sample_1_2
This is another C program.

うん、うまくいった。