PPT

C言語復習
来週もこの資料を持参してください
1
C言語の基礎
C言語,ソースファイルの作成,コン
パイル,実行
2
C言語
• プログラムとは,“計算機を動かす手順を
記述したもの”.
– 計算機に命令を与えて動かすには“プログラ
ムを作成する”ことになる.
• C言語はプログラミング言語の1個
– 手続き型言語に分類される.
– C/C++ は非常に多くの場面で使われる言語
• C++はC言語をオブジェクト指向に拡張したもの
3
C言語プログラミングの手順
• ソースファイルを作成し,コンパイルし,実
行.
“hello.c”
ソースファイル
source file
C言語
人間が記述する.
“hello.exe”
コンパイルする
compile
コンパイラ compiler
実行ファイル
executable exe
マシン語
通常人間に読めない
(Visual C++, gcc, bcc など)
・C言語では,ソースファイルを直接実行することができない.
ソースファイルをコンパイルして実行ファイルを作成し,実行ファイルを実行する.
・“ソースファイル” を “原始ファイル” と呼ぶこともある(ごくまれ).
・実行ファイルの拡張子はOSに依存する.Windows では “.exe” となる.
・厳密には,コンパイルとリンク(link)を行い実行ファイルを作る.
4
コンパイルとリンク
エディタ
コンパイラ
ソースファイル
“abc.c”
コンパイル
エディタ
コンパイラ
ソースファイル
“def.c”
コンパイル
オブジェクト
ファイル
“abc.o”
リンカ
オブジェクト
ファイル
“def.o”
リンク
実行ファイル
“xyz.exe”
標準ライブラリ
5
C言語のソースファイルの骨格
#include <stdio.h>
ヘッダ(header)ファイルの
読み込み.
先頭に必ず書く.
void main(){
void main(){
と
}
でプログラム本体を
挟む
ここにプログラムの本体を
記述する.
}
void main(){
と
}
でプログラム本体を
挟む
6
何も起きないプログラム
1
2
3
4
#include <stdio.h>
void main(){
}
半角で記述する.大文字と小文字は明確に区別される.
上記を入力し,実行する.
Error メッセージ,Warning(警告)メッセージ を確認する.
Errorは明確な誤りへのメッセージ
Warningは誤りではないが好ましくないことへのメッセージ
7
文字列を表示するプログラム
1
2
3
4
5
#include <stdio.h>
void main(){
printf("Hello, World!\n");
}
“Hello world!” と 表示するプログラム.
printf を 使えば,” ” で囲った文字列を表示できる.
“\n”は,改行を意味する.
printf(“Hello\nWorld!\n”);
として実行.動作を確認.
8
C言語の式と文
式
a
3 < a
10
3+4
a+4
"hello"
a++
a = 7
printf("hello")
文 (式文) は 式;
printf("hello");
a=3;
a++;
a;
正しいが,
通常あり得ない
9
C言語の文 (関数の呼び出し)
printf("Hello, World!\n");
関数名
関数の引数
セミコロン
関数の引数は()で囲み,中に式を書く.
10
文字列を表示するプログラム
1
2
3
4
5
6
7
#include <stdio.h>
void main(){
printf("Hello,\n");
printf("C lang.\n");
printf("World!\n");
}
上
か
ら
下
に
進
む
hello01.c
11
インデントとフリーフォーマット
#include <stdio.h>
void main(){
int i;
for(i=0; i<5; i++){
printf("i=%d\n", i);
}
}
#include <stdio.h>
#include <stdio.h>
void main(){
int i;
for(i=0; i<5; i++){
printf("i=%d\n", i);
}
}
void main(){
int i;
for(i=0; i<5; i++){
printf("i=%d\n", i);
}
}
↑対応関係がわかりづらい.
プログラム内の
空白,TAB文字,改行は
無視される.
よって,どのように
書いても問題ない.
当然,見やすく書くことが
好ましい.
↑対応関係が誤り.
#include <stdio.h>
void main(){ int i; for(i=0; i<5; i++){ printf("i=%d\n", i); }}
↑理解が困難.対応関係が分かりづらい.
12
コメント
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
/* と */ で挟まれた領域は,
コメントとして 無視される.
実行されない.
void main(){
/* print hello */
// print hello
printf("Hello,\n");
// から行末までの領域も,
コメントとして無視される.
実行されない.
/*
printf("World!\n");
*/
}
hello02.c
ただし,これはC++の機能であり
C言語の機能ではない.
(実際はほとんどのC言語のコンパ
イラにこの機能が付いている)
コメント部にはデタラメに書
いても問題ない.
正しいC言語の文も無視さ
れる.
13
数値計算を行う
変数,演算
14
演算結果の型
• X型とX型の演算結果はX型.
int a=7, b=2;
double d;
d = a + b;
d = a / b;
a + b は int型とint型の演算.
演算結果も int 型.
a+b は 9 (int型).
dには9.0 (double型)が入る.
a / b は int型とint型の演算.
演算結果も int 型.
a / b は 3 (int型).
dには 3.0 (double型)が格納される.
3.5 は格納されない.
15
演算結果の型
• X型とY型の演算結果はXorY型.
優先度の高い型が勝つ.
double > float > long > int > char の優先順
int a=7;
double d=2.0, e;
e = a / d;
a / b は int型とdouble型の演算.
double型が勝つので,
演算結果はdouble型.
7.0 / 2.0 と解釈され,
演算結果は 3.5 (double型).
16
演算結果の型
double d;
d = 7 / 2;
d = 7 / 2.0;
d = 7.0 / 2;
d = 7.0 / 2.0;
/* intとintの演算.結果はintの 3 */
/* intとdoubleの演算.
結果はdoubleの3.5 */
/* doubleとintの演算.
結果はdoubleの3.5 */
/* doubleとdoubleの演算.
結果はdoubleの3.5 */
17
制御文
18
真偽
条件が成り立つ場合,その条件式は真であ
る.
例えば,
(3 < 4) は真 true
(3 == 4) は偽 false
19
比較演算子
a==b
a!=b
a<b
a<=b
a>b
a>=b
:
:
:
:
:
:
aとbが等しい
aとbが等しくない
bはaより大きい
bはa以上(大きいか等しい)
aはbより大きい
注意!
aはb以上
比較
代入
a==b
a=b
OK
NG
!=
<=
>=
=!
=<
=>
20
論理演算子
条件 && 条件
論理積(and):両方成り立つ場合に真
条件 || 条件
論理和(or):少なくとも片方が成り立つ場合に真
!条件
否定(not):条件が成り立たないときに真.
真偽が逆転される
21
条件分岐 if 文
if( 条件式X ){
プログラムA
}
if( 条件式X ){
プログラムA
} else {
プログラムB
}
式Xが真の場合(成り立つ場合),
中身(プログラムA)が
実行される.
偽の場合(成り立たない場合)は
何も実行されない.
条件Xが真の場合
前半のプログラムAが
実行され,
偽の場合(成り立たない場合)
後半(else部)の
プログラムBが実行される
22
条件分岐 if 文
if( 条件式X ){
プログラムA
} else if( 条件式Y ){
プログラムB
} else if( 条件式Z ){
プログラムC
} else {
プログラムD
}
プログラムE
条件式Xが成り立つ場合,
プログラムAが実行され,
その後プログラムEに移る.
プログラムB,C,Dは全て“条件式Xのelse”の
中にあるため,たとえ条件式Yや条件式Zが成り立っ
ても実行されない.
条件式Xが偽の場合に限り,条件式Yが検証さ
れる.
条件式Xが偽で かつ 条件式Yが真 の場合,プ
ログラムBが実行され,プログラムEに移る.
プログラムC,Dは実行されない.
条件式Xが偽,条件式Yが偽,条件式Zが真の
場合,プログラムC,Eが実行される.
全てが偽の場合,プログラムD, Eが実行され
る.
23
条件分岐 if 文
1
2
3
4
5
6
7
8
9
#include <stdio.h>
void main(){
int a=12;
if( a < 10 ){
printf("a < 10 (a = %d)\n", a);
} else {
printf("10 <= a (a = %d)\n", a);
}
}
24
条件分岐 if 文
1
2
3
4
5
6
7
8
9
#include <stdio.h>
void main(){
int a=8;
if( a < 10 ){
printf("a < 10 (a = %d)\n", a);
} else {
printf("10 <= a (a = %d)\n", a);
}
}
25
条件分岐 if 文
#include <stdio.h>
void main(){
int a=8;
if( a < 10 ){
printf("A\n");
}
printf("B\n");
}
実行結果
A
B
26
条件分岐 if 文
#include <stdio.h>
void main(){
int a=12;
if( a < 10 ){
printf("A\n");
}
printf("B\n");
}
実行結果
B
27
条件分岐 if 文
#include <stdio.h>
void main(){
int a=23;
if( 10 <= a ){
printf("A\n");
}
if( 20 <= a ){
printf("B\n");
}
if( 30 <= a ){
printf("C\n");
}
}
実行結果
A
B
28
条件分岐 if 文
#include <stdio.h>
void main(){
int a=8, b=8;
if( a < 10 ){
if( b < 10 ){
printf("A\n");
} else {
printf("B\n");
}
} else {
if( b < 7 ){
printf("C\n");
} else {
printf("D\n");
}
}
}
実行結果
A
29
条件分岐 if 文
#include <stdio.h>
void main(){
int a=12, b=8;
if( a < 10 ){
if( b < 10 ){
printf("A\n");
} else {
printf("B\n");
}
} else {
if( b < 7 ){
printf("C\n");
} else {
printf("D\n");
}
}
}
実行結果
D
30
おまけ
著しく読みづらいソースコード
#include <stdio.h>
void main(){
int a=12, b=8;
if( a < 10 ){
if( b < 10 ){
printf("A\n");
} else {
printf("B\n");
}
} else {
if( b < 7 ){
printf("C\n");
} else {
printf("D\n");
}
}
}
31
条件分岐 if 文
#include <stdio.h>
void main(){
int a=12, b=8;
if( a < 10 && b < 10 ){
printf("A\n");
} else {
printf("B\n");
}
}
実行結果
B
32
条件分岐 if 文
#include <stdio.h>
void main(){
int a=12, b=8;
if( a < 10 || b < 10 ){
printf("A\n");
} else {
printf("B\n");
}
}
実行結果
A
33
条件分岐 if 文
#include <stdio.h>
void main(){
int a=12, b=8;
if( ! (a<10||b<10) ){
printf("A\n");
} else {
printf("B\n");
}
}
実行結果
B
34
真偽
厳密には,C言語には条件や真や偽はない.
値(式分)が「0以外」なら真,「0」なら偽とみ
なす.
注意:NULL は「0」なので 偽 である.
if( 1+2 ){
プログラムA
} else {
プログラムB
}
「3」は真を意味する.
結果,プログラムAに入る
「0」は偽を意味する.
結果,プログラムBに入る
if( 4-4 ){
プログラムA
} else {
プログラムB
}
C言語になれるまでは,このような変な(?)表現は使わなくて良い. 35
繰り返し for 文
• 同じ処理を何度も繰り返すには for 文を使う.
int i;
for( i=0; i<5; i++){
処理A;
}
例
int i;
for(i=0; i<3; i++){
printf("Hello!\n");
}
int i;
for(i=0; i<7; i++){
printf("World!\n");
}
処理Aを
5 回繰り返す.
結果
結果
Hello!
Hello!
Hello!
World!
World!
World!
World!
World!
World!
World!
36
繰り返し for 文
int i;
for(i=0; i<3; i++){
printf("Hello,\n");
printf("World!\n");
}
i=0 として
printf("Hello,\n");
printf("World!\n");
i=1 として
printf("Hello,\n");
printf("World!\n");
i=2 として
printf("Hello,\n");
printf("World!\n");
(i=0; i<3; i++)
「i が 0 から 3未満の範囲で(2まで),
繰り返す.i は1ずつ増える.」
という意味の 繰り返し.
i=0 → iが0から始まる.
i<3 → iが3未満である限り続ける
i++ → i は1ずつ増える
i が“0から3未満(2まで)”なので,
i =0, i =1, i=2 の3回繰り返す.
printf("Hello,\n");
printf("World!\n");
printf("Hello,\n");
printf("World!\n");
printf("Hello,\n");
printf("World!\n");
37
繰り返し for 文
int i;
for(i=10; i<13; i++){
printf("i=%d\n",i);
}
「i が 10 から始まり 13未満の範囲で
(12まで),繰り返す.i は1ずつ増える.」
という意味の 繰り返し.
結局,i=10, i=11, i=12 の3回繰り返す.
int i;
for(i=0; i<6; i+=2){
printf("i=%d\n",i);
}
「i が 0 から始まり 6未満の範囲で,
繰り返す.i は2ずつ増える.」
という意味の 繰り返し.
結局,i=0, i=2, i=4 の3回繰り返す.
int i;
for(i=2; 0<=i; i--){
printf("i=%d¥n",i);
}
「i が 2 から始まり 0 以上の範囲で,
繰り返す.i は1ずつ減る.」
という意味の 繰り返し.
結局,i=2, i=1, i=0 の3回繰り返す.
38
繰り返し for 文
int i;
for(i=10; i<3; i++){
printf("i=%d\n",i);
}
「i が 10 から始まり,3未満の範囲で,
繰り返す.i は1ずつ増える.」
という意味の 繰り返し.
結局,(10<3が偽なので)1回も実行しない.
int i;
for(i=3; 0<=i; i++){
printf("i=%d\n",i);
}
「i が 3 から始まり,0以上の範囲で,
繰り返す.i は1ずつ増える.」
という意味の 繰り返し.
結局,無限に繰り返す.
int i;
for(i=0; ; i++){
printf("i=%d¥n",i);
}
「i が 0 から始まり,無条件で,
繰り返す.i は1ずつ増える.」
という意味の 繰り返し.
結局,無限に繰り返す.
39
繰り返し for 文
• 動作原理
int i;
for(i=0; i<3; i++){
printf("Hello,\n");
printf("World!\n");
}
printf("End\n");
i=0;
N
i<3?
Y
printf("Hello,\n");
printf("World!\n");
i++;
printf("End\n");
40
繰り返し for 文
• 動作原理
i=0;
i<3?
printf("Hello,\n");
printf("World!\n");
int i;
for(i=0; i<3; i++){
printf("Hello,\n");
printf("World!\n");
}
i++; /*i=1となる*/
i<3?
printf("Hello,\n");
printf("World!\n");
i++; /*i=2となる*/
i<3?
printf("Hello,\n");
printf("World!\n");
i++; /*i=3となる*/
終了
i<3?
41
繰り返し for 文
for( 式1; 式2; 式3 ){
プログラム
}
最初に式1を行う
式2が真である限り,
ブロックの中身を繰り返す.
1回繰り返すたびに式3を
行う.
int i;
for (i=0; i<2; i++){
printf("i=%d\n",i);
}
iが0になる.
i<2 の真偽を調べる.真である(i=0).
よって,forの中のブロックに入る.
printf()を実行.
ブロックが終わり,i++を行い,ブロックの
最初に戻る.
i<2 の真偽を調べる.真である(i=1).
よって,forの中のブロックに入る.
printf()を実行.
ブロックが終わり,i++を行い,ブロックの
最初に戻る.
i<2 の真偽を調べる.偽である(i=2).
よって,forを終了する.
42
繰り返し for 文
• for文の中にfor文
int i, j;
for(i=0; i<3; i++){
for(j=0; j<4; j++){
printf("Hello\n");
}
}
同義
int i, j;
for(i=0; i<3; i++){
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
}
黄:Helloと1回表示.
青:Helloと4回表示.黄色を4回繰り返す.
結果,4回×3回=12回繰り返す.
43
繰り返し for 文
• for文の中にfor文
int i, j;
for(i=0; i<3; i++){
for(j=0; j<4; j++){
printf("i=%d,j=%d\n",i,j);
}
}
『printf() をj=0~3の4回繰り返す』を
i=0~2の3回繰り返す.
結果,4回×3回=12回繰り返す.
44
繰り返し while 文
while( 条件式X ){
プログラムA
}
条件Xが真である限り,
中身(プログラムA)を
繰り返し実行する.
毎回,条件式を評価してから,
プログラムを実行する.
int i=0;
while( i<2 ){
printf("i=%d\n",i);
i++;
}
iが0になる.
i<2 の真偽を調べる.真である(i=0).
よって,whileの中のブロックに入る.
printf()を実行.
i++ により i が1になる.
ブロックが終わり,ブロックの最初に戻る.
i<2 の真偽を調べる.真である(i=1).
よって,whileの中のブロックに入る.
printf()を実行.
i++ により i が2になる.
ブロックが終わり,ブロックの最初に戻る.
i<2 の真偽を調べる.偽である(i=2).
よって,whileを終了する.
45
繰り返し do-while 文
do{
プログラムA
}while(条件式X );
iが0になる.
条件Xが真である限り,
中身(プログラムA)を繰り返し実行する.
毎回,プログラムを実行してから,
条件式を評価する.
よって,最低でも1回は実行される.
int i=0;
do{
printf("i=%d\n",i);
i++;
} while( i<2 );
printf()を実行.
i++ により i が1になる.
ブロックが終わり,i<2 の真偽を調べる.
真である(i=1).
よって,再度,whileブロックの中を実行.
printf()を実行.
i++ により i が2になる.
ブロックが終わり,i<2 の真偽を調べる.
偽である(i=2).
よって,再度,whileブロックの中を実行.
46
break による 繰り返しの中断
int i;
for(i=0; i<10; i++){
printf("i=%d\n",i);
if( i==3 ){
break;
}
} 繰り返し中断
実行結果
printf(“Fin!\n“,i);
i=0
i=1
i=2
i=3
Fin!
break; を実行すると,
繰り返しが中断される.
47
無限ループ
for(;;){
printf("Hello, World!\n");
}
while(1){
printf("Hello, World!\n");
}
for文で条件部を書かないと,
無条件で繰り返し.
無限ループとなる.
while文で条件部に1と書くと,
条件が必ず成立するので
無限ループとなる.
(1は真偽における“真”である
ため.)
48
例
1, 4, 9, 16, 25, 36,…,100と出力
int i, x;
for(i=1; i<=10; i++){
x = i*i;
printf("%d\n", x);
}
49
配列
50
C言語:変数の宣言と利用
• 変数の宣言
“ i ”という名前の整数型変数を宣言.
以後 i を使用可能.
i は,整数を格納(記録)できる箱.
int i;
“ d ”という名前の
double d;
浮動小数点型変数を宣言.
i = 3;
変数 i に整数 3 を代入.
以後, i には 3 が入っている.
d = 5.7;
printf("i=%d, d=%lf\n", i, d);
プログラム
実行結果
i=3, d=5.700000
51
C言語:配列の宣言と使用
• 配列
配列の宣言
int型が3個の配列. (変数の作成)
data[0]~data[2]
が使用可能.
int data[3];
int i;
配列の使用
"0から始めて,3未満"
data[0] = 3;
(作成済みの変数の
でfor文を使うと
data[1] = 4;
使用)
やりやすい.
data[2] = 5;
for(i=0; i<3; i++){
data[0]=3
printf("data[%d]", i);
data[1]=4
printf("=%d\n", data[i]);
data[2]=5
}
実行結果
プログラム
52
C言語:2次元配列
int data[3][2];
int型が2×3=6個の配列.
int i, j;
data[0][0]~data[2][1]
data[0][0] = 3; data[0][1] = 4;
が使用可能.
data[1][0] = 5; data[1][1] = 6;
「長さ2個の配列」が3個.
data[2][0] = 7; data[2][1] = 8;
(長さ3の配列が2個でない)
for(i=0; i<3; i++){
for(j=0; j<2; j++){
data[0][0]=3
printf("data[%d][%d]", i, j);
data[0][1]=4
printf("=%d\n", data[i][j]);
}
data[1][0]=5
}
data[1][1]=6
プログラム
data[2][0]=7
data[2][1]=8
実行結果
53