2017年06月16日
情報科学類 コンピュータリテラシ
                                       筑波大学 システム情報系 情報工学域
                                       新城 靖
                                       <yas@cs.tsukuba.ac.jp>
このページは、次の URL にあります。
	http://www.coins.tsukuba.ac.jp/~yas/coins/literacy-2017/2017-06-16
/c-lang.html
あるいは、次のページから手繰っていくこともできます。
	http://www.coins.tsukuba.ac.jp/~yas/
	http://www.cs.tsukuba.ac.jp/~yas/
The Unix Super Text 第57章 Cの使いかた 参照。
$ mkdir ~/c_progs ![[←]](../icons/screen-return.gif) $ cd ~/c_progs
$ cd ~/c_progs ![[←]](../icons/screen-return.gif) $ ls
$ ls ![[←]](../icons/screen-return.gif) (何も表示されない。mkdir 直後は、ディレクトリは空。)
$ cp ~yas/public_html/htdocs/coins/literacy-2017/2017-06-16/ex/hello.c .
(何も表示されない。mkdir 直後は、ディレクトリは空。)
$ cp ~yas/public_html/htdocs/coins/literacy-2017/2017-06-16/ex/hello.c . ![[←]](../icons/screen-return.gif) $ ls
$ ls ![[←]](../icons/screen-return.gif) hello.c
$ cat hello.c
hello.c
$ cat hello.c  ![[←]](../icons/screen-return.gif) #include <stdio.h>
#define NAME "(name)"
int main()
{
        printf("Hello, %s\n", NAME );
}
$ cc hello.c
#include <stdio.h>
#define NAME "(name)"
int main()
{
        printf("Hello, %s\n", NAME );
}
$ cc hello.c  ![[←]](../icons/screen-return.gif) $ ls
$ ls ![[←]](../icons/screen-return.gif) a.out   hello.c
$ ./a.out
a.out   hello.c
$ ./a.out  ![[←]](../icons/screen-return.gif) Hello, (name)
$
Hello, (name)
$ ![[]](../icons/screen-cursor.gif) 
c_progs で C programs の意味。
各自、自分の分かりやすい名前に置き換えること。
a.out という
ファイルに保存される。
$ cat error.c  ![[←]](../icons/screen-return.gif) #include <stdio.h>
#define	 NAME "(name)"
int main()
{
	printf("Hello, %s\n", NAME )
}
$ cc error.c
#include <stdio.h>
#define	 NAME "(name)"
int main()
{
	printf("Hello, %s\n", NAME )
}
$ cc error.c  ![[←]](../icons/screen-return.gif) error.c:7:30: error: expected ';' after expression
        printf("Hello, %s\n", NAME )
                                    ^
                                    ;
1 error generated.
$
error.c:7:30: error: expected ';' after expression
        printf("Hello, %s\n", NAME )
                                    ^
                                    ;
1 error generated.
$ ![[]](../icons/screen-cursor.gif) 
この場合は、cc は、実行ファイルを作らない。
ファイル名と行番号をたよりに、プログラムを修正して、
エラーが出なくなるまで cc を実行する。
コンパイル・エラーがでなくなっても、プログラムは完成ではない。コンパイ ラにはわからない(分かり得ない) 間違いは残っている可能性がある。
$ ls ![[←]](../icons/screen-return.gif) a.out   hello.c
$ rm a.out
a.out   hello.c
$ rm a.out  ![[←]](../icons/screen-return.gif) $ ls
$ ls ![[←]](../icons/screen-return.gif) hello.c
$ cc -o hello hello.c
hello.c
$ cc -o hello hello.c  ![[←]](../icons/screen-return.gif) $ ls
$ ls ![[←]](../icons/screen-return.gif) hello   hello.c
$ ./hello
hello   hello.c
$ ./hello  ![[←]](../icons/screen-return.gif) Hello, (name)
$
Hello, (name)
$ ![[]](../icons/screen-cursor.gif) 
#include で読み込まれる。
stdio.h などのヘッダ・ファイルは、/usr/include/ 以下に
ある。他の場所にある時には、cc コマンドに -I オプションで
指定する。
libc (library C)という
ライブラリにある関数を標準で自動的に取り出して結合する(リンクする)。
libc などよくつかわれるライブラリは、
/usr/lib にある。
libc 以外のライブラリを使う時には、cc に -l オプションを付ける。
たとえば、三角関数 sin(), 指数関数 exp() 等を使う時には、-lm (mathematicsの意味)を指定する。
/usr/lib 以外の場所にあるライブラリを使うには、-L オプションで
ディレクトリのパス名を与える。
例:f1.c, f2.c, f3.c という3つのファイルに含まれているC言語のプログラ ムをすべてコンパイルして、リンクし、完成した実行可能なプログラムを prog という名前のファイルに保存する。
$ ls f1.c f2.c f3.c ![[←]](../icons/screen-return.gif) f1.c    f2.c    f3.c
$ cc -o prog f1.c f2.c f3.c
f1.c    f2.c    f3.c
$ cc -o prog f1.c f2.c f3.c ![[←]](../icons/screen-return.gif) $
$ ![[]](../icons/screen-cursor.gif) 
毎回、全部のファイルをコンパイルすると、遅い。
ソース・ファイルを変更したプログラムだけをコンパイルしたい。
$ ls f*.c ![[←]](../icons/screen-return.gif) f1.c    f2.c    f3.c
$ ls f1.*
f1.c    f2.c    f3.c
$ ls f1.* ![[←]](../icons/screen-return.gif) f1.c
$ cc -c f1.c
f1.c
$ cc -c f1.c ![[←]](../icons/screen-return.gif) $ ls f1.*
$ ls f1.* ![[←]](../icons/screen-return.gif) f1.c    f1.o
$ ls f2.*
f1.c    f1.o
$ ls f2.* ![[←]](../icons/screen-return.gif) f2.c
$ cc -c f2.c
f2.c
$ cc -c f2.c ![[←]](../icons/screen-return.gif) $ ls f2.*
$ ls f2.* ![[←]](../icons/screen-return.gif) f2.c    f2.o
$ ls f3.*
f2.c    f2.o
$ ls f3.* ![[←]](../icons/screen-return.gif) f3.c
$ cc -c f3.c
f3.c
$ cc -c f3.c ![[←]](../icons/screen-return.gif) $ ls f3.*
$ ls f3.* ![[←]](../icons/screen-return.gif) f3.c    f3.o
$ ls f*.c
f3.c    f3.o
$ ls f*.c ![[←]](../icons/screen-return.gif) f1.c    f2.c    f3.c
$ ls f*.o
f1.c    f2.c    f3.c
$ ls f*.o ![[←]](../icons/screen-return.gif) f1.o    f2.o    f3.o
$ cc -o prog f1.o f2.o f3.o
f1.o    f2.o    f3.o
$ cc -o prog f1.o f2.o f3.o ![[←]](../icons/screen-return.gif) $ ./prog
$ ./prog  ![[←]](../icons/screen-return.gif) This is main().
This is f1().
This is f2().
This is f3().
$
This is main().
This is f1().
This is f2().
This is f3().
$ ![[]](../icons/screen-cursor.gif) 
(分割)コンパイルを楽にするためのプログラム。 どのようなファイルをコンパイルすればよいかの 定義を与えると、ファイルの日付を比較して、 自動的にコンパイルとリンクを行う。
$ ls *.c ![[←]](../icons/screen-return.gif) f1.c    f2.c    f3.c    hello.c
$ ls *.o
f1.c    f2.c    f3.c    hello.c
$ ls *.o ![[←]](../icons/screen-return.gif) ls: *.o: No such file or directory
$ cat Makefile
ls: *.o: No such file or directory
$ cat Makefile ![[←]](../icons/screen-return.gif) all: prog
objs = f1.o f2.o f3.o
prog: $(objs)
        $(CC) -o prog $(objs)
$ make
all: prog
objs = f1.o f2.o f3.o
prog: $(objs)
        $(CC) -o prog $(objs)
$ make ![[←]](../icons/screen-return.gif) cc    -c -o f1.o f1.c
cc    -c -o f2.o f2.c
cc    -c -o f3.o f3.c
cc -o prog f1.o f2.o f3.o
$ ls *.c *.o prog
cc    -c -o f1.o f1.c
cc    -c -o f2.o f2.c
cc    -c -o f3.o f3.c
cc -o prog f1.o f2.o f3.o
$ ls *.c *.o prog ![[←]](../icons/screen-return.gif) f1.c    f1.o    f2.c    f2.o    f3.c    f3.o    hello.c prog
$
f1.c    f1.o    f2.c    f2.o    f3.c    f3.o    hello.c prog
$ ![[]](../icons/screen-cursor.gif) 
all: prog objs = f1.o f2.o f3.o prog: $(objs) $(CC) -o prog $(objs)