C言語入門

1
C言語入門
第10週
プログラミング言語Ⅰ(実習を含む。),
計算機言語Ⅰ・計算機言語演習Ⅰ,
情報処理言語Ⅰ(実習を含む。)
2
基本型
3
標準ヘッダ: <limits.h>
• 整数型の最小値・最大値は以下のマクロで
定義されている
unsigned
signed
最小値
最大値
最小値
最大値
char
0
UCHAR_MAX
SCHAR_MIN
SCHAR_MAX
short
0
USHRT_MAX
SHRT_MIN
SHORT_MAX
int
0
UINT_MAX
INT_MIN
INT_MAX
long
0
ULONG_MAX
LONG_MIN
LONG_MAX
char 型に関する定義
CHAR_BIT
char 型のビット数
CHAR_MIN
0 または SCHAR_MIN
CHAR_MAX
UCHAR_MAX または SCHAR_MAX
4
標準ヘッダ: <float.h>
• 浮動小数点型に関する定数は以下のマクロ
で定義されている
float
double
指数表現の基数
FLT_RADIX
DBL_RADIX
精度の10進桁数
FLT_DIG
DBL_DIG
仮数部における基数(RADIX)の桁数
FLT_MANT_DIG
DBL_MANT_DIG
1.0 + 𝑥 ≠ 1.0となる最小の𝑥
FLT_EPSILON
DBL_EPSILON
最大値
FLT_MAX
DBL_MAX
正規化された最小の浮動小数値
FLT_MIN
DBL_MIN
RADIX 𝑛 − 1が表現可能な𝑛の最大値
FLT_MAX_EXP
DBL_MAX_EXP
10𝑛 を正規化された浮動小数値として表現可能な𝑛の最小値
FLT_MIN_EXP
DBL_MIN_EXP
5
エラーメッセージを読みエラーの原因を推測しましょう
良くあるエラーの例
6
gcc のエラーメッセージ
• 環境変数LANGを設定すると言語が変わる
mintty + bash + GNU C
$ LANG=C gcc error1.c
error1.c: In function 'main':
error1.c:7:3: error: expected ';' before 'printf'
printf("world\n");
^
mintty + bash + GNU C
$ LANG=ja_JP.UTF-8 gcc error1.c
error1.c: 関数 ‘main’ 内:
error1.c:7:3: エラー: expected ‘;’ before ‘printf’
printf("world\n");
^
ロケール(locale)と呼ばれる
多言語化の仕組み
JM: locale (7)
7
mintty の locale の設定
• mintty左上のアイコンからoption→Text
ここに
Locale: ja_JP
Cahaacter set: UTF-8
を設定して「OK」しておく
8
文末の「;」忘れ
• 文末に「;」を忘れると次の文字でエラーに
4
5
6
7
8
9
10
error1.c
mintty + bash + GNU C
int main()
{
printf("hello, ")
printf("world\n");
$ gcc error1.c
error1.c: 関数 ‘main’ 内:
error1.c:7:3: エラー: expected ‘;’ before ‘printf’
printf("world\n");
^
return EXIT_SUCCESS;
}
エラーが生じたのは7行目の3文字目だが、エラーの原因は6行目の行末。
C言語では、スペースや改行は人間に読み易くするための位置調整に過ぎないので
printf("hello, ")
ここに「;」があるべきだが
printf("world\n");
「;」の前に「p」が現れたことが
は
printf("hello, ")printf("world\n"); エラーの原因
と同じ意味。
9
ブロック開始終端の不整合
• 「{」が1つ多い
4
5
6
7
8
9
10
error2_1.c
mintty + bash + GNU C
int main()
{
{
printf("hello, world\n");
$ gcc error2_1.c
error2_1.c: 関数 ‘main’ 内:
error2_1.c:10:1: エラー: expected declaration or statement at end of input
}
^
return EXIT_SUCCESS;
}
「}」が1つ足らない状態で、ファイルの終端(入力の終端)に達している。
10
ブロック開始終端の不整合
• 「}」が1つ多い
4
5
6
7
8
9
error2_2.c
mintty + bash + GNU C
int main()
{
printf("hello, world\n");
}
return EXIT_SUCCESS;
}
$ gcc error2_2.c
error2_2.c:8:3: エラー: expected identifier or ‘(’ before ‘return’
return EXIT_SUCCESS;
^
error2_2.c:9:1: エラー: expected identifier or ‘(’ before ‘}’ token
}
^
エラーが生じたのは8行目の3文字目だが、エラーの原因は7行目。
「}」が1つ多いので、main関数の定義が7行目で終わっている。
つまり、8~9行目は、何もないところにいきなり以下のように書いたのと同じ。
8
9
return EXIT_SUCCESS;
}
11
ブロック開始終端の不整合
• 関数名のミススペル
4
5
6
7
8
9
error3.c
mintty + bash + GNU C
int main()
{
print("hello, world\n");
$ gcc error3.c
/tmp/ccopiKHp.o:error3.c:(.text+0x15): `print' に対する定義されていない参照です
/tmp/ccopiKHp.o:error3.c:(.text+0x15): 再配置がオーバーフローしないように切り詰め
られました: R_X86_64_PC32 (未定義シンボル `print' に対して)
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../x86_64-pc-cygwin/bin/ld:
/tmp/ccopiKHp.o: 誤った再配置アドレス 0x0 がセクション `.pdata' 内にあります
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../x86_64-pc-cygwin/bin/ld: 最終
リンクに失敗しました: 無効な操作です
collect2: エラー: ld はステータス 1 で終了しました
return EXIT_SUCCESS;
}
コンパイルではなくリンクに失敗したと言われている。
分割コンパイルによる、外部関数のリンクの際、print が見つからなかった。
printf のつもりが print とミススペルしている。
標準ライブラリに print 関数は用意されていない。
コンパイルフェーズではなくリンクフェーズでのエラー。
~.o ファイルについて参照がみつからないと言われている。
12
不要な ;
• 関数定義がプロトタイプ宣言になっている
4
5
6
7
8
9
error4.c
mintty + bash + GNU C
int main();
{
printf("hello, world\n");
$ gcc error4.c
error4.c:5:1: エラー: expected identifier or ‘(’ before ‘{’ token
{
^
return EXIT_SUCCESS;
}
main() の直後に ; があるのでそこで文が終わっている。
このため、関数の定義ではなく、関数のプロトタイプ宣言になっている。
13
ファイルが見つからない
• ファイル名や配置場所を確認する
1
2
3
4
5
6
7
8
9
error5.c
mintty + bash + GNU C
#include <stdio.h>
#include <stdilb.h>
$ gcc error5.c
error5.c:2:20: 致命的エラー: stdilb.h: No such file or directory
#include <stdilb.h>
^
コンパイルを停止しました。
int main();
{
printf("hello, world\n");
return EXIT_SUCCESS;
}
#include しようとしたファイルが見つからない。
#include に与えたファイル名か、ファイルに付けた名前のどちらかが間違っている。
上記の例では stdlib.h が正しいが lib ではなく ilb になっている。
コンパイルフェーズではなく、プリプロセスフェーズでのエラー
14
C言語のコンパイル
• コンパイラにより実行形式に変換する
Source files
C compiler
.h ファイル
.h ファイル
.h ファイル
Preprocessor
Object files
.c ファイル
.c ファイル
.c ファイル
.o ファイル
.o ファイル
.o ファイル
Cコンパイラは実際には
preprocessor
compiler
linker
の3段階に分かれている
C compiler
linker
Executable files
実行ファイル
ライブラリ
ライブラリ
ライブラリ
15
エラー時の対処方法
• エラーメッセージをよく読みましょう。
• 行番号と何文字目かも参考になります。
• 同じようなエラーメッセージなら、同じような原
因である可能性が高いはずです。
• 原因が分からない場合は、エラーメッセージ
を Google 等の検索エンジンで検索しましょう。
16
参考文献
• [1] B.W.カーニハン/D.M.リッチー著 石田晴久
訳、プログラミング言語C 第2版 ANSI 規格準
拠、共立出版(1989)