プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf ·...

26
プログラミング演習第一 第1回目:プログラミング開発環境とコンパイル A10/4() 1-2B10/5() 1-2担当:上瀧 剛(こうたき ごう) http://www.cs.kumamoto-u.ac.jp/~koutaki/pukiwiki/ Mail:[email protected]

Transcript of プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf ·...

Page 1: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラミング演習第一

第1回目:プログラミング開発環境とコンパイル

A組 10/4(月) 1-2限

B組 10/5(火) 1-2限

担当:上瀧 剛(こうたき ごう)

http://www.cs.kumamoto-u.ac.jp/~koutaki/pukiwiki/

Mail:[email protected]

Page 2: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

演習の目標:

C言語の文法の習得。

・関数(サブルーチン)

・配列、ポインタ、構造体

評価:

・レポート課題のみ。試験はありません。

・ただし、プログラミング方法論が不合格の場合、

本演習も不合格となります。

・2/3の出席が必要。レポート回収で出席を兼ねます。

・やむを得ず欠席する場合は必ず事前に連絡下さい。

事前連絡なしではレポートを受理しません。

Page 3: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

スケジュール(予定)

何の役に立つのか:

卒業研究、就職活動、会社での業務、etc…

回 A組 B組 教科書の項目 内容

1 10/4 10/5 C言語プログラムの作成C言語のやさしい入門

コンパイル・hello world

2 10/4 10/5

3 10/18 10/12 printf詳細、getc, make

4 10/25 10/19 変数とデータ型 変数、配列、文字列

5 11/8 10/26 演算子 四則演算、型キャスト、ビット

6 11/15 11/9 制御文 if, for, while, break, continue

7 11/22 11/16 コンソール入力 getchar, putchar

8 11/29 11/30 関数の作り方 関数宣言、グローバル宣言、記憶クラス9 12/6 12/7

10 12/13 12/14 ポインタ アドレス、ポインタ参照

11 12/20 12/21

12 1/17 1/11 ユーザが作成するデータ型 構造体、共用体

13 1/24 1/18

14 1/31 1/25 プリプロセッサ、標準ライブラリ、ファイル入出力

実用プログラム

Page 4: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラミング言語のタイプタイプ 備考 コード例 コンパイラ

(ファイル)

FORTRAN 最初の高級言語。科学計算ソフト系(ex.行列演算、電

子状態計算)ではいまだに現役だったりします。

INTEGER I, J

DO I=0, 10 j = j + iENDDO

F77, G77(*.f,*.f77,*f90)

C C++と並んで開発系で最もよく使われる言語。

int i, j = 0;

for(i = 0;i <= 10;i++)j = j + i;

gcc, VisualC++(cl.exe)Boland C++(*.c, *.h)

アセンブラ 機械語に近い言語。SIMD並列処理

や高速処理が要求される箇所で、部分的に使われることがある。

mov eax,dword ptr [ebp+0Ch]test eax,eaxje 765CCDA1mov ecx,dword ptr fs:[18h]

Visual C++Gas(*.asm)

C++ おそらく開発系で最もよく使われる言語。基本はC言語。

Int j = 0;for(int i = 0;i <= 10;i++)

j = j + i;

Gcc, VisualC++(cl.exe)Boland C++(*.cpp, *.cc)

Java 開発系でよく使われる言語。基本はC言語の文法に似ている。

Int j = 0;for(int i = 0;i <= 10;i++)

j = j + i;

Javac(*.java)

他にもいろいろあります

Page 5: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

本日の演習内容プログラミング開発環境とコンパイル

0. C言語でのプログラム作成手順

1.簡単なC言語のプログラム作成

2.コンパイルと実行

3.エラー、警告メッセージについて

4.まとめ

5.課題

Page 6: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

0. C言語でのプログラム作成手順

C言語のプログラムソースを作成(人間が読みやすい形式)

コンパイル(コンピュータが理解できる形式に翻訳)

実行ファイル(バイナリ)出力

テキストエディタを使います。Emacsやvi。Windowsだとメモ帳など。

翻訳プログラムをコンパイラといいます。演習ではgcc(GNU C Compiler)というコンパイラを使います。Windowsだと、VC++(cl.exe)などがあります。

実行ファイルを実行

ライブラリ(既にコンパイル済みのプログラムや関数群)

リンク

Windowsだとexeファイルに相当します。

リンクを行うプログラムをリンカといいます。gccにはリンカ機能も含まれています。

Windowsのパソコンを持っている人は、Cygwinというソフトをインストールすることで本演習とほぼ同等の環境でgccを使うことができます。

Page 7: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

ご参考:Cygwinの実行例

Page 8: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

1.簡単なC言語のプログラム作成

Emacsを起動して以下のプログラムソースを作成して、ex1-1.cとして

保存してください。

>mkdir PEI

>cd PEI mv ex1-1.c PEI ・・・ファイルをPEIに移動

>emacs ex1-1.c &

#include <stdio.h>

int main(void){

printf(“hello, world!¥n”);

return 0;

}

Page 9: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

2.コンパイルと実行

ソースを保存したら、以下のコマンドを実行してプログラムをコンパイルします。

問題なければ、次のプロンプト > が表示されます。

何かメッセージが出てくれば、どこかでプログラムを打ち間違えていますので

修正してください。

>gcc ex1-1.c

>

コンパイル

実行

>./a.out

hello, world!

>

以下のコマンドを入力して、先ほどコンパイルしたプログラムを実行します。

「hello, world!」と出てくれば成功です。

Page 10: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラム解説

int main(void){

printf(“hello, world!¥n”);

return 0;

}

メイン関数がここから{hello, world!¥nという文字列を出力する戻り値=0としてメイン関数を終了するメイン関数ここまで}

■ Cのプログラムはmain関数から開始されます。

関数の中身はカッコ{ }で閉じます。

■文はセミコロン;で区切ります。

■ printfは画面に文字列を出力する関数です。標準関数と呼ばれる関数です。

その宣言・定義は先のstdio.hに書かれています。

では、その処理を行う関数の中身は?

→標準ライブラリ/usr/lib/libc.a の中に入っています。

おそらく、gccの作者がマシン語(画面出力というハードウェア制御が

入っている)などで作ってますので解読難。

■main関数はint型(整数の値)を返さなければなりません。

ですのでreturn 0;が入っています。

Page 11: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラム解説

int main(void){

printf(“hello, world!¥n”);

return 0;

}

文は字下げで見やすくします。

int main(void){

printf(“hello, world!¥n”);

{

int a;

}

return 0;

}

Page 12: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラム解説

int main(void){

printf(“hello, world!¥n”);

return 0;

}

メイン関数がここから{hello, world!¥nという文字列を出力する戻り値=0としてメイン関数を終了するメイン関数ここまで}

printf(“hello, world!¥n”);文字列はダブルクォーテション“”で囲みます。

¥nは(あるいはバックスラッシュ/n)は改行の意味です。

他にも以下のようなものがあります。

printfは他にも機能がありますが、別途説明します。

¥n 改行 ¥t タブ

¥r 行の先頭に戻る ¥a ビープ音を鳴らす

¥¥ ¥を表示 ¥” “を表示

Page 13: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

プログラム解説

#include <stdio.h>

int main(void){

printf(“hello, world!¥n”);

return 0;

}

テキスト出力関数printfを使うために、printfが宣言されているヘッダファイルを読む。stdio=Standard Input Outputの略

#はプリアンブルの意味で、ヘッダファイルの内容をそのまま置き換える。

ではstdio.hはそもそもどこにあるのか?→/usr/include/の中にある。

Page 14: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

>grep "printf" /usr/include/stdio.h

extern int fprintf (FILE *__restrict __stream,extern int printf (__const char *__restrict __format, ...);extern int sprintf (char *__restrict __s,extern int vfprintf (FILE *__restrict __s, __const char *__restrict __format,extern int vprintf (__const char *__restrict __format, _G_va_list __arg);extern int vsprintf (char *__restrict __s, __const char *__restrict __format,extern int snprintf (char *__restrict __s, size_t __maxlen,

__THROW __attribute__ ((__format__ (__printf__, 3, 4)));extern int vsnprintf (char *__restrict __s, size_t __maxlen,

__THROW __attribute__ ((__format__ (__printf__, 3, 0)));extern int vasprintf (char **__restrict __ptr, __const char *__restrict __f,

__THROW __attribute__ ((__format__ (__printf__, 2, 0)));extern int __asprintf (char **__restrict __ptr,

__THROW __attribute__ ((__format__ (__printf__, 2, 3)));extern int asprintf (char **__restrict __ptr,

__THROW __attribute__ ((__format__ (__printf__, 2, 3)));extern int vdprintf (int __fd, __const char *__restrict __fmt,

__attribute__ ((__format__ (__printf__, 2, 0)));extern int dprintf (int __fd, __const char *__restrict __fmt, ...)

__attribute__ ((__format__ (__printf__, 2, 3)));extern int obstack_printf (struct obstack *__restrict __obstack,

__THROW __attribute__ ((__format__ (__printf__, 2, 3)));extern int obstack_vprintf (struct obstack *__restrict __obstack,

__THROW __attribute__ ((__format__ (__printf__, 2, 0)));

プログラム解説確認

>grep “printf” /usr/include/stdio.h

確かにある。

#include<stdio.h>はこの長いヘッダファイルの中身を貼り付けている。

Page 15: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

gccについて

>gccソースプログラムのファイル名 –o 出力ファイル名 –lライブラリファイル名

-o はOutputの略。このオプションを省略すると、a.outが出力ファイルとなる。

-l でライブラリファイル内の関数を出力ファイルにリンクします。

・デフォルトでは –lc (libc.a:標準関数群)、-lm(libm.a:数学関数群)が

リンクされます。

・ライブラリファイルは/usr/libに置いてあります。通常、ここのディレクトリを

gccは探しにいきます。

・ライブラリファイルの中には沢山の関数が詰まっています。

・gccは賢いので、ソースプログラム内で使われた関数だけを取り出して

自動的にリンクしてくれます。

Page 16: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

1.簡単なC言語のプログラム作成以下のプログラムソースを作成して、ex1-2.cとして保存・コンパイル・実行してください。

/* 数値計算をするサンプルプログラム*/

#include <stdio.h>

int main(void){

int nn; // 変数nnを宣言

nn = 4 + 5; // 4 + 5 の結果を変数nnに入れる

printf(“%d + %d = %d¥n”, 4, 5, nn); // 結果を表示する

return 0;

}

printf(“%d + %d = %d¥n”, 4, 5, nn);

%dは整数値を表示します。その整数値は、カンマ「,」の後にそれぞれ指定します。

Page 17: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

1.簡単なC言語のプログラム作成

/* コメント文 */

// コメント文

/*************************************/

/* プログラムmain.c by g.koutaki */

/* 2010.10.3 ver.1 */

/*************************************/

/************************************

プログラムmain.c by g.koutaki

2010.10.3 ver.1

************************************/

コメント文の例

/* と */ の間で囲まれた文をコメントにする。途中で改行しても、その間はコメント扱いになる。

// 以降をコメントにする。改行するとコメントを抜ける。C++からの仕様だが、Cでも使える場合が多い。

Page 18: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

3.エラー、警告メッセージについて・エラー(error)

スペルミスや文法ミスでコンパイルが通らない状態。

言われた箇所を直せば基本的にすぐ直る。

・警告(warning)

エラーではないが、望ましくないコードである。

→プログラムは実行できる。が、致命的なバグの原因になる

可能性があるので、なるべく警告は出さないように努める。

・バグ(bug)

エラーも警告もないが、プログラムがとまったり、望ましくない

結果が得られる。忌わしき事態。バグ取りは、ソフトウェア開発

でもっとも時間を要する作業。

Page 19: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

3.エラー、警告メッセージについて例)わざとエラーを出してみる。

>cp ex1-1.c ex1-3.c

としてファイルをコピー。以下のように変更してみる。

#include <stdio.h>

int main(void){

printf(“hello, world!¥n”);

return 0;

// }

次のようなエラーが出る。>gcc ex1-3.c

ex1-3.c: In function „main‟:

ex1-3.c:6: error: expected declaration or statement at end of input

main関数ないでエラーがある。関数の終端がない。

// はコメント文の意味。この行は無視されます。

Page 20: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

3.エラー、警告メッセージについて例)わざと警告を出してみる。以下、ex1-4.cを作成する。

#include <stdio.h>

int main(void){int a, b;b = 1 / 0;printf(“hello, world!¥n”);return 0;

}

次のような警告が出る。>gcc ex1-3.c -Wall

ex1-3.c: In function „main‟:

ex1-3.c:6: warning: division by zero

ex1-3.c:5: warning: unused variable „a‟

警告をすべて出すようにオプション-Wallを指定

main関数のなかで変数aを宣言したが一度も使っていない。

ゼロで除算を行った。

Page 21: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

3.エラー、警告メッセージについて例)わざとバグを出してみる。ex1-5.cとして保存する。

#include <stdio.h>

int main(void){int index;int data[100];data[index] = 100;index = index + 1;return 0;

}

これを作った人はindexは0で初期化されていると勘違いしていたとする。

次のようなにコンパイルは問題なく通るが、プログラムを実行すると強制終了する。>gcc ex1-5.c –Wall

> ./a.out

Segmentation fault (core dumped)

>メモリ関連で深刻なエラーが発生!

このdata[100]は配列変数です。別途、演習で詳しく解説します。

Page 22: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

3.エラー、警告メッセージについてindexの値を調べてみる。

#include <stdio.h>

int main(void){int index;int data[100];printf(“index=%d¥n”, index);data[index] = 100;index = index + 1;return 0;

}

実際にはindexにおかしな値が入っていた。

> ./a.out

index=1629747862

Segmentation fault (core dumped)

Page 23: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

4.まとめ

・プログラムは、

ソース作成→コンパイル→ソース修正

の流れで行う。

・コンパイルを行うプログラムはコンパイラ。

・コンパイラはエラーや警告を教えてくれる。

・エラーや警告がなくても生じる不具合(バグ)がある

Page 24: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

5.課題課題1-1.以下のプログラムを作成してコンパイルした結果を

示しなさい。その結果について解説しなさい。

課題1-2.上のプログラムがコンパイルが通るように修正しなさい。

また、その実行結果を示しなさい。結果が思わしくない

場合は、その原因について考察しなさい。

#include <stdio.h>

int main(void){

int a, b;

a = 0;

b = 1 / a;

printf(“a = %d, b = %d¥n”, a, b)}

Page 25: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

5.課題課題2.

学籍番号下3桁を下図のようにo(小文字のオー)を

組み合わせて表示するプログラムを作成して、結果を表示せよ。

レポートにはプログラムソースも載せること。

一文字のサイズは横5×縦8文字で、文字間は2文字分

空けること。文字のデザインは読めれば何でもいいです。

oooo o

oooo

ooooooo

oooo o

oooo

oo

o oooo

oooo oo ooooo

ooo

ooo

Page 26: プログラミング演習第一 - 熊本大学koutaki/PEI_2010/pe_1.pdf · C言語のやさしい入門 コンパイル・hello world 2 10/4 10/5 3 10/18 10/12 printf詳細、getc,

レポートのフォーマットについて

2010/10/11

プログラミング演習第一 第1回課題レポート

103-T1234 上瀧 剛

課題1-1.

(1)コンパイルの結果

(2)結果の解説

….

課題1-2.

(1)ソースプログラム

#include <stdio.h>

int main(void){int a, b;a = 0;

>gcc ex1-1.c….