第 1 章 : 序論

コンピュータに仕事をさせるための手順

C言語で記述されたプログラムは、そのままではコンピュータで実行することができません。 C言語で書いたプログラム(ソースコード)を、コンパイル(Complile)、リンク(Link)と呼ばれる処理を行い、コンピュータで実行可能な機械語のプログラム(実行コード)を作成する必要があります。

  • ソースコード : C言語などのプログラミング言語でプログラムを記述したもの
  • オブジェクトコード : ソースコードをコンパイルし機械語に翻訳したもの
  • 実行コード : オブジェクトコードを結合し、実行に必要な情報を付与したりして、コンピュータで実際に実行可能とした機械語のコード

例題 1-1 : プログラムの作成・コンパイル・実行

C 言語でプログラムを作成してコンパイルを行って実行コードを生成し、実行するまでの手順を体験してみましょう。

この先たくさんのプログラムを作成していきます。 どのファイルがどの課題のものなのか分からなくなくならないように、まずはプログラミング実習用のディレクトリを作成し、 そのディレクトリの下に、課題ごとのディレクトリを作成するとよいでしょう。

端末
$ cd ~
$ mkdir programming
$ cd programming
$ mkdir ex_1_1
$ cd ex_1_1
$ pwd
~/programming/ex_1_1

ここではホームディレクトリにプログラミング実習用のディレクトリ programming を作成し、さらにその下に、この例題用のディレクトリ ex_1_1 をつくりました。

作成した例題用のディレクトリ内でプログラムを作成していきましょう。 初めにソースコードを作成します。 エディタ(Emacs, Vim, VSCode など)で次のプログラムを作成を作成し、ファイル名を hello.c として保存してください。 なお、 C 言語のソースコードのファイル(ソースファイル)の拡張子は .c とする必要があります。

hello.c
#include <stdio.h>

int main(void) {
  printf("Hello, World!\n");

  return 0;
}

gcc コマンドを用いてソースファイルを指定し、コンパイル(とリンク)を行います。 端末で以下のように入力しましょう。

端末
$ gcc hello.c -o hello
$ ls
hello  hello.c

gcc コマンドの -o オプションでは、コンパイルしてできる実行コードのファイル名を指定しています。 ファイルの一覧を取得する ls コマンドで実行コード hello があることを確認しましょう。

コンパイルができたら、実際に実行コード hello を実行してみましょう。 端末で以下のように入力し、実行コード hello を実行します。

プログラムに誤りがなければ、標準出力に Hello, World! と表示され、改行されます。

端末
$ ./hello
Hello, World!
$

Tip

ソースコードに構文エラー(文法上の誤り)があると、コンパイラはコンパイルに失敗し、次のようなエラーメッセージやヒントを表示します。 エラーメッセージをよく確認し、ソースコードを修正したうえで再度コンパイルを行いましょう。

端末
$ gcc first.c -o first
first.c: In function ‘main’:
first.c:4:42: error: expected ‘;’ before ‘return’
    4 |   printf("This is my first C program!\n")
      |                                          ^
      |                                          ;
    5 | 
    6 |   return 0;
      |   ~~~~~~      

C言語のプログラミングおよびそのコンパイルと実行の手順に慣れるためにもう一つ例題に取り組みましょう。

例題 1-2 : プログラムの作成・コンパイル・実行 (その2)

以下のソースコード second.c を作成しましょう。 (programming ディレクトリの下に新たに ex_1_2 ディレクトリを作成して、ex_1_2 ディレクトリで作業を行うとよいでしょう。)

second.c
#include <stdio.h>

int main(void) {
  printf("This is\nmy second project\n");
  printf("WoW!");
  printf("Cool!\n");
  return 0;
}

gcc で second.c をコンパイル(とリンク)し、実行コード second を作成しましょう。

端末
$ gcc second.c -o second
$ ls
second  second.c

実行コードを実際に実行し、どのような実行結果となるかを確認しましょう。

端末
$ ./second
This is
my second project
WoW!Cool!

gcc にはコンパイラとリンカの両方の機能が備わっています。 プログラミング基礎で扱うような小規模なプログラムの開発では、 例題 1-1 で行ったように gcc でソースコードから直接実行コードを作成しても問題ありませんが、複数のソースコードを必要とする大規模な開発では、コンパイルとリンクを分けて行うことが多いです。

参考のために、コンパイルとリンクを分けて実行コードを作成する方法を体験しておきましょう。

例題 1-3 : (optional) コンパイルとリンク

まず、この例題用のディレクトリを作成し、そのディレクトリに移動します。 次に示す、2つのソースコード main.cmyfunc.c を作成してそれぞれ保存してください。

main.c
#include <stdio.h>

void myfunc(void);

int main(void) {
  printf("Hello, Here main.c!\n");
  myfunc();
  return 0;
}
myfunc.c
#include <stdio.h>

void myfunc(void) {
  printf("Here, myfunc.c\n");
}

gcc の -c オプションを用いて、2つのソースコードに対してコンパイルのみを行い、オブジェクトコードを作成します。

端末
$ gcc -c main.c myfunc.c
$ ls
main.c  main.o  myfunc.c  myfunc.o

ls でファイルを確認すると、2つのオブジェクトコード main.omyfunc.o が作成されているのがわかります。

次にリンカを用いて、オブジェクトコードを結合し実行コードを咲く作成します。

リンカは複数のオブジェクトコードやライブラリを結合して、コンピュータ上で直接実行できる実行コードを作成するものです。

以下のように gcc で2つのオブジェクトコード main.omyfunc.o を指定してリンクし、-o オプションで指定した実行コード main を作成しましょう。

端末
$ gcc main.o myfunc.o -o main
$ ls
main  main.c  main.o  myfunc.c  myfunc.o

実行コード second を実行すると次のように表示されるはずです。

端末
$ ./main
Hello, Here main.c!
Here, myfunc.c
$

演習

演習 1-1 : 10までカウント

次のソースコード count10.c をコンパイルして実行し、プログラムの動作を確認しましょう。

count10.c
#include <stdio.h>

int main(void) {
  int count;

  for (count = 1; count <= 10; count++) {
    printf("%d ", count);
  }

  printf("end!\n");

  return 0;
}

端末に表示された実行結果の部分をコピーして、テキストファイルを作成し、ファイル名 count10_log.txt として保存してください。

端末
$ ./count10
1 2 3 4 5 6 7 8 9 10 end!
$ 

ソースコード count10.c と実行結果 count10_log.txt の2つのファイルを課題へ提出してください。