C language Sem 01

Preview:

DESCRIPTION

C言語に関する勉強会の資料

Citation preview

C/C++ ゼミ (1)

プログラムの原理、 C 言語の原理

2008.4.12

agenda

プログラムの原理• プログラムとは• 抽象化• コンピュータ・アーキテクチャ• コンパイラ

C 言語の基礎知識• 歴史的な話• 本題

• 変数• 関数• Hello World!

プログラムの原理

プログラムとは プログラムへの命令

•手間がかかってめんどい作業を、コンピュータにやらせて楽をする

html や tex はプログラムではない

プログラム言語

Via http://www.itmedia.co.jp/enterprise/articles/0703/26/news021.html

0 と 1

コンピュータは 0 と 1 しか理解できない

コンピュータへの命令も 0 と 1 だけで書く必要がある

……0010011101010001……

さすがに理解不能

マシン語 0 と 1 の命令を、ちょっとだけ読み

やすくした•論理的意味ごとに区切ってある•16 進数に変換してある場合も

10110000 01100001 00110000…

まだきつい

アセンブリ言語 数字を言葉におきかえた

10110000 01100001

MOV AL, 61

CPU によって命令の名前が変わっちゃう

高級言語 Fortran, Pascal, C とかが登場 アセンブリ言語よりわかりやすい 書き方も CPU に依存しなくなった

そのかわり、実行時間は遅くなった

MOV AL, 61

a = 61

プログラム言語

Via http://www.itmedia.co.jp/enterprise/articles/0703/26/news021.html

プログラム言語はさらに進化 オブジェクト指向

• C++• Java

LL (lightweight language)• Perl• PHP• Ruby• Phyton• javascript

プログラム言語

Via http://www.itmedia.co.jp/enterprise/articles/0703/26/news021.html

言語の水準 開発(プログラムを書く)のは楽で

はやい できたプログラムの実行速度はおそ

い スピードが求められる場面では、低

水準言語をつかう 低水準 = 使えない、古い ではない !

なんでこんなにたくさん言語が?

最終的には 0 と 1 どの言語を使っても、同じプログラ

ムは書ける•チューリング完全というらしい…

ただ、それぞれ得意分野がある それぞれやりたいことに適した言語

を選ぶのが大事

抽象化

抽象化とは 必要なものだけを集める いらないものを省く ( イメージしやすいよう名付ける )

01→ マシン語→アセンブラ→高水準言語これも抽象化

抽象化とは 人は、ある一定以上複雑なことにつ

いて、考えられない 抽象化して、ものごとをわかりやす

く、無駄なことを考えなくてすむようにする

抽象化で複雑さに対抗! コンピュータなんて抽象化でできて

るようなもん

たとえば

“a = 6” は、アセンブリ言語であらわすと数行になる•必要な処理をまとめている

現実世界にある” =“ を使っているから、処理をイメージしやすい

MOV AL, 61

a = 61

データと手続き プログラムはデータと手続き ( 制御 )

でできている

プログラムプログラム

データを入力 加工 出力

構造化プログラミング アセンブラから高水準言語になった

けど、やっぱりまだむずかしい…

手続きを抽象化しよう!•順番に実行する•条件によって分岐する•何度も繰り返す•サブルーチン

順番に実行する ( 順次 )

処理 1処理 1 処理 2処理 2 処理 3処理 3

条件によって分岐する ( 分岐 )

条件条件 処理 1処理 1 処理 2処理 2

何度も繰り返す ( 反復 )

条件条件 処理 1処理 1 処理 2処理 2

手続き抽象化 この三つで、すべてのアルゴリズム

を記述できる ( らしい ) 組み合わせ爆発をおさえつつ、記述

力は減少していない !

サブルーチン 関数 (C とか ) 、プロシジャともいう いくつかの処理をひとまとめにし、

ブラックボックス化したもの 中身はさっきの 3 つ ( 順次・分岐・

反復 ) で書く

サブルーチンサブルーチン

入力 加工 出力

サブルーチンのいいところ ブラックボックスなので、中身を気にせ

ず使い方だけ知っておけばよい• 本来の作業に集中できる

再利用できる ( ライブラリ )• 誰か ( 世界中 !) が作ったのを、流用できる

変更があったとき、そのサブルーチンの中身だけを直せばよい• 他のルーチンには影響しない

処理をイメージしやすい

構造化プログラミング 大小のサブルーチンで構成 メインルーチンがサブルーチンを呼

び出しながら処理を進める サブルーチンの中身は順次・分岐・

反復で書く

構造化プログラミング

メインルーチン

サブルーチン

サブルーチン

サブルーチン

サブルーチン

サブルーチン

入力

出力

データ抽象 手続きは抽象化できたけど、データ

はまだ複雑… データに手続きをくっつける

•データがこういう場合はこう加工する•手元に来るのは、適切に加工されたデ

ータ

オブジェクト指向

気をつけること 抽象化の度合いと、プログラムの実行時

間はトレードオフ• 適切なレベルのツールを選ぶ必要がある

0 と 1 の世界0 と 1 の世界

マシン語とかマシン語とか

低水準低水準

高水準高水準

超高水準超高水準 超高水準超高水準抽象度高

抽象度低

らくちん

はやい

気をつけること サブルーチンはブラックボックス でも、中のアルゴリズムがどういう仕組みかは、知っておくべき

ここがよく分かってないと…•効率の悪いプログラムになってしまう•うまくいかなかったとき、どこが悪い

のかわからない

コンピュータ・アーキテクチャ

コンピュータの構成

CPUCPU ハードディスク

メモリメモリ

入力インタフェース入力インタフェース 出力インタフェース出力インタフェース

マウス、キーボード、カメラ ディスプレイ、プリンタ、スピーカ

CPU

計算・加工するところ•実際に計算する部分•処理の順番を決める部分•命令を解釈する部分•データを置いておく部分•外部とデータを受け渡しする部分

データはレジスタに入れておく

レジスタ データを置いておくところ 読み込み、書き込みが超速い ひとつの CPU に、いくつかついてい

て、それぞれ名前もある

Via http://en.wikipedia.org/wiki/Central_processing_unit

メモリとアドレス レジスタに入りきらないデータはメモリにおいておく•必要になったらレジスタに入れて計算

する メモリにはアドレスがある

アドレス0001

0002

0003

メモリデータデータデータ

ハードディスク レジスタやメモリは、電源を切ると

終わる 長くデータを保存しとく時は、ハー

ドディスクをつかう アクセス時間は超遅い

プログラムとメモリ プログラムは普段 HD にある 実行するとき、メモリに移される 必要なときにレジスタにデータを移

して計算

CPUCPU ハードディスク

メモリメモリ

レジスタ 遅い 超遅い速い

コンパイラ

コンパイラ ソースコードを、コンピュータでも理解

できる 0 と 1 に翻訳してくれるソフト•文を解析• 間違いをチェック• 最適化• 実行可能オブジェクト (.exe とか ) を生成

コンパイラコンパイラ

コンパイル

ソースコード

実行可能オブジェクト

インタプリタ 命令を受け取って、逐次実行してい

インタプリタインタプリタ

命令

実行

命令

実行

スクリプト 一文ずつ入力するのはめんどいから

列挙する→スクリプト インタプリタはスクリプトを上から

順番に読んで実行していく スクリプトは台本という意味

コンパイラとインタプリタ コンパイラ

•最終的に完結した一つのファイルを作る

•できたファイルの実行速度は速い•コンパイルには時間がかかる

インタプリタ•スクリプト単体では動かない•手軽•でかいスクリプトになると遅い

とりあえずコンパイルしてみる hello.c

• “hello world” と出すプログラム

a.out ができるので、実行する

$ gcc hello.c

$ a.out

アセンブリ C のコンパイラは、コンパイルする

さい、コードを一度アセンブリ言語に変換する

のぞいてみる

$ gcc hello.c –S$ gedit hello.s

リンク ソースコードをコンパイルすると、

オブジェクトファイルができる いくつかのオブジェクトファイルを

つなげて ( リンク ) 、最終的にひとつの実行可能オブジェクトができる•ライブラリを使ったら、ライブラリと

もリンクさせる

ソースコード オブジェクト

ライブラリ

実行可能オブジェクトコンパイル

リンク

さっきのコマンドでは、アセンブルして、途中でオブジェクトを作って、リンクまでしてくれているが、ここら辺は自動化されている

$ gcc hello.c

リンクしてみる hello21.c と hello22.c

$ gcc hello21.c –c hello21.o$ gcc hello22.c –c hello22.o$ gcc hello21.o hello22.o –o hello2$ hello2

hello21.c のオブジェクトファイルを作る hello22.c のオブジェクトファイルを作る hello21.o と hello22.o をリンクして、実行可能オブジェクト hello2 を作る hello2 を実行する

バイナリ 実行可能オブジェクトは、 0 と 1 の

集まりになっている バイナリデータという バイナリ: 2 進数 画像とかもバイナリ形式

バイナリファイルの中を見てみる

警告は無視しよう

$ gedit hello2

C 言語の基礎知識

C 言語 ( 歴史的な話 )

リッチーとカーニハンが開発( AT&T ベル研 )

仕様がシンプル コンパイラ

C と C++ と Java

C++ は C に機能を追加したもの Java は C++ を結構参考にしている

C やっとけばオッケー

抽象度の水準 抽象度の水準がちょうど良いと言わ

れている•実行スピードと開発効率

抽象度が低いので、かなり勉強になる (ポインタとか )

C やっとけばオッケー

ANSI C

89年に、 C が標準化された ANSI C とよばれる 今のコンパイラはほぼ全部これに従

っている

ANSI C やっとけばオッケー

本題

C のプログラムの構成 関数と文と変数 関数

• サブルーチン 関数は 1 つ以上の文から成る

• 関数は 1 つ以上の文から成る•色んな処理を書いたもの• “;” で終わる

変数• データをいれるところ• 実際にはメモリ

変数

変数 実際にはメモリ

•メモリ上のどこかに、データを置く領域を確保している

•抽象化されているので、プログラマは実際にはメモリのどこにデータがあるかとかを気にしなくて良い

好きな名前を付けられる データ型がある

データ型 整数、少数、文字、ポインタ

•そのデータが何なのか、プログラマが知る手がかりとなる

•コンパイラが、間違いを検出できる (文字を足し算したとか )

宣言 変数を使う前に、宣言をする必要が

ある•宣言した段階で、メモリ上に領域を確保する

•宣言されてない変数が出てくると、コンパイラはメモリのどこを見ればいいのかわからないので、エラーを出す

•変数のスペルミスを防ぐ役割にもなってる

コード

/* 変数の宣言 */int a;double b;

a = 10;b = 1.5;

メモリのイメージ

アドレス0001

0002

0003

メモリ10

??

1.5

aa

bb

関数

関数 いわゆるサブルーチン

関数を呼び出す

printf : 関数名 () の中 : 関数へ渡すデータ ( 引数 )

» 引数が沢山ある場合は、” ,” で区切って列挙する

printf(“hello world!!”);

関数名 ( 引数リスト );

関数からの出力がある場合

出力は” =“ で変数に代入する 関数からの出力を返り値という

result = pow( 5, 2);

関数を自作int square ( int n ){

int result;

result = n*n;return result;

}

返り値の型 関数名 ( 引数リスト ){中身

}

関数を宣言する 自作関数は、プログラムの冒頭で宣

言する必要がある•プロトタイプ宣言•プロトタイプ宣言がないと、コンパイ

ラはその関数がどこに書いてあるかがわからない

プロトタイプ宣言

int square( int n );

int main(void){

...val = square( 5 );...

}

int square( int n ){

...}

void

引数や返り値がない関数もある 宣言と本体を書く際” void” といれ

int foo(void);

void woo( int n ){...

}

printf の宣言や本体はどこにある?

プロトタイプ宣言はヘッダファイル(stdio.h) に書かれている

本体はライブラリという別ファイルに書かれている

#include <stdio.h>

Int main(void)

{

int printf(...);

int printf(...)

{

}

stdio.h自作ファイル ライブラリ

Hello World!

Hello World!

入力してコンパイル、

#include <stdio.h>

int main(void){

printf(“hello world!\n”);

return 0;}

#include

ヘッダファイルを読み込むための、特別な命令

頭に # がつく命令は、文末に” ;” がいらない ( プリプロセッサ・ディレクティブ )

stdio.h には、 printf のプロトタイプ宣言が入っている

標準ライブラリ C に最初からついてくるライブラリ 便利な関数がいっぱい

•stdio.h•stdlib.h•math.h•string.h• ...

main

メインは特別な関数 必ず最初に実行される ここから色んな関数を呼び出す

printf

標準出力に文字を出す関数•標準出力は、デフォルトではターミナ

ル (設定で変えられる ) 文字か文字列を与えてあげる

•文字列は”で囲む

\n と文字 エスケープシーケンス 普通ではあらわしづらい文字 (改行

やタブやバックスペースなど ) を表現する

\n は改行 \t はタブ

今後の予定

予定! データ型、演算子、式 制御の流れ 関数 ポインタと配列 (2,3回 ) 構造体 C++ へ

Recommended