02: c 言語の基礎...c 言語の歴史1973 年、それまで機械語で書かれていたunix...

76
02: 変数, Linux にログインし、以下の講義ページを開 いておくこと http://www-it.sci.waseda.ac.jp/teachers/ w483692/CPR1/ C プログラミング入門 基幹7 (5) 1 2017-04-19

Upload: others

Post on 20-Feb-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

02: 変数, 式

Linux にログインし、以下の講義ページを開いておくこと

http://www-it.sci.waseda.ac.jp/teachers/

w483692/CPR1/

C プログラミング入門基幹7 (水5)

1

2017-04-19

Page 2: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

アンケート結果 (4/19 15:00)

42

26

20 1

05

1015202530354045

Linux の経験

Linux の経験

21

44

60

0

10

20

30

40

50

C 言語の経験

C 言語の経験

2

回答数 71単位:人

Page 3: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

C 言語の歴史

1973 年、それまで機械語で書かれていた UNIX の開発を簡単にするために AT&T 研究所の Dennis Ritchie が開発

すでにつくられていたB言語を改良

1978年、Dennis Ritchie と Brian Kernighan が解説書“The C Programming Language” を出版 (通称 K&R)

3

Page 4: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

言語仕様の規格

1978: K&R

• “The C Programming Language”

1989:ANSI C (C89)

• ISO/IEC 9899:1990

• JIS X 3010:1993

1999: C99

• ISO/IEC 9899:1999

• JIS X 3010:2003

2011: C11

• ISO/IEC 9899:2011

4

デファクトスタンダード

C99/C11 に対応した教科書などは最近徐々に増加している

現在も C89 の仕様が一般的に使用されているANSI C 準拠などと書かれる

大改訂

Page 5: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

講義で学ぶ事項

文法

•主に C89

•キーワードや式

データ構造

•コンピュータでのデータの扱い

アルゴリズム

•問題を解く方法

標準ライブラリ

•何が提供されているのか

•どのように使用するのか

5

主に秋期「C プログラミング」で扱う

Page 6: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

基本事項

8

Page 7: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

プログラムの様々な名称:全体 9

#include <stdio.h>

int main(void)

{

printf("Hello, world!¥n");

return 0;

}

関数定義main という関数を定義している

ディレクティブ特殊な指定

※数学でいう関数とは意味合いが異なる

※詳しい解説はあとで。

Page 8: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

プログラムの様々な名称: 関数 10

#include <stdio.h>

int main(void)

{

printf("Hello, world!¥n");

return 0;

}

関数名

文 (関数呼び出し)

文 (制御構造)

キーワード

Page 9: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

疑問

#include って何しているの?

int とか void って何?

最後の return 0 の意味は?

今後少しずつ、解説していきます

11

Page 10: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

C 言語の全体構造

幾つかの関数 (function) で構成される

手続き (procedure) とも呼ばれ、C は手続き型言語と呼ばれる。関数型言語ではない(詳しくは調べてください)

main という名前の関数を必ず一つ含む

数学でいう関数とは似ているところもあるが異なる

OS はプログラムを実行すると、 main 関数を呼び出す(=実行する)

12

Page 11: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

関数とは

プログラムを構成する単位

任意の関数名の後に引数列と呼ばれる部分を含む ( ) が付き、そのあとに文が続く

幾つかの文の列が { } に囲まれて書かれる

上から順に実行される

各文は、; (セミコロン) で終わる

複数の文を { } で囲んでまとめたものをブロックという

13

#include <stdio.h>

int main(void)

{

printf("Happy ");

printf("New ");

printf("Year!!¥n");

return 0;

}

$ ./prog

Happy New Year!!

実行結果

Page 12: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

フリーフォーマット (free formatting)

字句(トークン)の区切りが明確なら、自由に空白や改行を入れることが出来る。

書き方のルールをコーディングスタイルという。

バグを減らす・他人と共有する・未来の自分が読むためには、読みやすくすることが重要

14

#include <stdio.h>

int main(void)

{

printf("Hello, world!¥n");

return 0;

}

空白で区切り

行を開ける

ブロック内を字下げ

Page 13: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

フリーフォーマットの例

以下の3つの例はすべて同じ正しいプログラム

どれが読みやすいですか?

15

#include <stdio.h>

int main (

void) { printf( "Hello,

world!¥n" );

return

0; }

#include <stdio.h>

int main(void){printf("Hello, world!¥n");return 0;}

#include <stdio.h>

int main(void)

{

printf("Hello, world!¥n");

return 0;

}

Page 14: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

ホワイトスペース (whitespace)

以下のようなものが連続したものを

ホワイトスペースと呼ぶ

空白 (space)

タブ (tab)

幅が設定によって可変

改行文字

エディタ上では折り返して表示される

空白類文字

空白、タブ、改行(といくつか)の総称

ホワイトスペース(空白類文字列)

空白類文字の連続

16

Tab |

Enter ↲

対応するキー

Page 15: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

字下げ・インデント (indentation)

ブロックの中を字下げして、読みやすくする

人によって書き方が違う

空白 8 つ

空白 4 つ

空白 2 つ

タブ 1 つ

講義資料では空白 2 つ分

17

#include <stdio…

int main(void)

{

printf("Hello…

return 0;

}

タブと空白は見た目で区別ができませんが必ず使い分けることレポートの評価対象の一つ

#include <stdio…

int main(void)

{

printf("Hello…

return 0;

}

不適切なインデント

Page 16: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

コメント (comment, remark)

/* と */ で囲まれた部分

入れ子にはできない

内容は無視される

ソースコード内に、情報を書き込むために使用

C99 では // で始まるコメントも追加された

行末までがコメントとなる

もともと C++ 言語で使われる文法

一般的なコンパイラでは独自拡張として対応

C89 では仕様違反だが、使用しても問題になることはおそらく無い

18

Page 17: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

コメントの例 19

/*

* こんにちは世界、と表示するプログラム

* by Mochizuki

*/

#include <stdio.h>

/* メイン関数 */

int main(void)

{

// print a message

printf("Hello, world!¥n"); // Cool!

return 0;

}

Page 18: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

コンピューターにできること:計算

コンピューターは計算を間違えない

20

Page 19: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

整数と実数

C言語で行える計算は主に、整数と実数に大きく分かれる

printf は計算結果を表示できる

%d: 整数の表示

%f: 実数の表示

計算をする部分を式という

21

#include <stdio.h>

int main(void)

{

printf("%d¥n", 2+3);

printf("%f¥n", 1.5/2);

return 0;

}式

Page 20: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

計算とリテラル (literal)

数値の計算を行うコードを式 (expression) という

式ではリテラル (定数)・演算子・変数名・関数呼び出しを使うことができる

式の例

30 – (radius * radius * 3.14) / sin(0.1)

22

変数名 変数名

演算子 演算子 演算子演算子演算子

整数リテラル

浮動小数点リテラル

浮動小数点リテラル

演算子(関数呼び出し)

Page 21: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

整数リテラル

10進数

0 100 2014

+2013 -30

16進数: 0~9, A~F で表現

0x1A 0x001A 0x07de 0xFFFF

8進数

07 012

リテラルではないもの(エラーとなる)

☠08

23

2014 65535

8 進数では 8 は使わない10 進数に 0 を追加したものとはみなされない

7 10

26 26

0xの後に 0 を追加してよい

型は、その値を表現できる最小の整数型となる明示的に型を指定する接尾辞を付加することもできるがここでは省略する

正確には符号はリテラルの一部ではなく演算子

10進数の12ではない

Page 22: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

浮動小数点リテラル

小数

3.14

1.

.5

-.3

指数表現(科学技術形式)

6.02e23 1E3

314e-2

2.3e-04

24

6.02 × 103

ただし、 3.14 がメモリ表現として正確に表せるかどうかは別問題である通常は近似値である(前述)

型は、接尾辞で明示的に指定しない限り double となる

1.0 × 103

314 × 10−2 = 3.14

2. 3 × 10−4

Page 23: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

文字列リテラル・文字リテラル

文字列リテラル

"Awesome cat"

"Hello, world¥n"

文字: 文字を表すコードになる

'a' 'C'

'¥n'

文字リテラルではないもの(エラーとなる)

☠'abc'

25

型は char ではなくint である。

特殊な文字を表すためにバックスラッシュ ¥ を使う

型は char * (char へのポインタ) である。詳細については文字列の回で説明

文字リテラルは 1 文字しかかけない

文字列リテラルを char 型変数に入れることはできない

Page 24: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

四則演算子

1 + 10

3 - 9

.2 * 1.5

1.1 / 2

剰余演算子

9 % 4 (9 を 4 で割った余り = 1)

優先順位の変更

3 * ( 1 + 2.5 ) / 2

基本的な演算子 (operators)

除算

乗算

26

整数同士の演算は整数になる実数を含むと結果は実数になる

Page 25: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

ビット演算子 (ビットごとに行われる)

演算: & | ^ ~

シフト: << >>

関数呼び出し

printf("hello")

その他の演算子

C の規格では算術シフトか論理シフトかは未定義

AND

27

OR XOR NOT

Page 26: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

整数同士の除算の注意

整数同士の計算結果は整数というルールから、切り捨てが発生する

28

(5 + 2) / 2

⇓ (+ 演算子の評価)

7 / 2

⇓ (/ 演算子の評価)

3

(5 + 2) / 2.0

7 / 2.0

3.5

整数リテラル 浮動小数点リテラル

結果が整数となった少なくとも一方が浮動小数なら結果は浮動小数になる

Page 27: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

演算の順序

どの演算子から演算を行うかは優先順位と結合方向で決まっている(詳しくはリファレンス参照)

優先順位

異なる演算子の演算順番

おおよそ数学の用法に近いが、一部は直観と反する

結合方向

同じ演算子、または優先順位が同じ演算子の順序

a+b+c は (a+b)+c (左から右) となるなど

29

Page 28: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

コンピューターにできること:記憶

コンピューターはデータを忘れない

30

Page 29: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

コンピューター

周辺機器 (peripheral)

コンピューターの計算の仕組み 31

CPU

int main(void){printf(“...

010001000011010101010101011111010101010101010101010101001010111111111100000001010101010110100101

実行ファイルの中身=機械語

(machine language)

ソースコード

コンパイル

実行

記憶装置(memory)

読み書き

I/O 制御

Page 30: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリ(記憶装置)

CPU が読み書きする装置

コンピュータが計算する=メモリの読み書き

2つの状態を持つスイッチのようなものがたくさん並んで入っている

状態は変更するまで維持される(記憶)

電気を切ると状態が失われる(揮発性)

数、文字、画像、動画、音声などを記憶する

どうやって?

32

Page 31: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリのサイズ

状態 1 つ分を bit, 8 つで byte という単位で表現する

例: 4GB のメモリ

= 4 × 1024 MB

= 4 × (1024)2 KB

= 4 × (1024)3 byte

= 4 × (1024)3 × 8 bit = 68,719,476,736 bit

33

1 byte (B)

1 bit

色で、電荷の状態 (スイッチのON/OFF に対応) を表現

Page 32: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリ上の表現: 数値

正の整数は 2 進法で表現

8bit では 0~255 の 256 通り表現可能

負の整数は最上位ビットを符号とみなす

複数の表現がある

小数

IEEE754 などの規格 難しいけどうまくできそうですよね?

34

正の整数 2進数

0 00000000

1 00000001

2 00000010

… …

254 11111110

255 11111111

■■■■■■□■■□□■■□□■■□

253 25

メモリの状態を 0 か 1 とみなして、8 bit ごとに整数だと思う場合の例

とにかく数値表現にすることができれば、メモリに格納できる

Page 33: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリ上の表現: 文字

文字それぞれに番号(文字コード)を割り当てる→数値化

文字コードの種類

ASCII

• アルファベットのコード(右表)

JIS 漢字コード

• 日本語用の文字コード

Unicode

• 世界中の文字に番号を振ったコード

etc…

35

0 1 2 3 4 5 6 7

0 0 @ P ` p

1 ! 1 A Q a q

2 " 2 B R b r

3 # 3 C S c s

4 $ 4 D T d t

5 % 5 E U e u

6 & 6 F V f v

7 ' 7 G W g w

8 ( 8 H X h x

9 ) 9 I Y I y

A * : J Z j z

B + ; K [ k {

C , < L ¥ l |

D - = M ] m }

E . > N ^ n ~

F / ? O _ o

Page 34: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリ上の表現: 画像

グレースケール画像の場合

サイズをあらかじめ決めておく

1ピクセルの濃淡値を 0~255 で表現 (0:黒, 255:白)

36

48 52 122 …

1マスは 8bit (1byte) で整数を表したもの

カラーの場合は通常 RGB の 3 バイトで1ピクセルを表現

メモリの中身

画像は画素の集まりでできている。これをディジタル画像という。

Page 35: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

データ表現

どんなデータでも、数値として表すことができれば、メモリやファイルに格納できる

C 言語では、整数や小数だけでなく、画像のような複雑な構造を持ったデータを簡単に扱える機能がある

以下のデータをどうやってメモリやファイルに格納するか?どうやって探し出すか?を考えるのが秋期の講義の目的

学生の成績情報

回路の配線図

地震のシミュレーション

音楽

パズルの答え

etc…

37

Page 36: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

変数の利用

38

Page 37: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリの概念図

メモリ: 0/1 の状態を大量に保持する装置

この講義で用いるメモリの概念図

1本の帯で表現し、その帯の一部分を見ている

連続する bit 列を 8bit (=1byte) ずつ区切る

何も書かれていないマスも必ず何かの状態を保持していることに注意

39

たとえば 00110110 といった状態列(ビット列)を持っている

前後にずっと続いている

1つの四角が 1 byte を表現

前後にずっと続いている

Page 38: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

メモリに値を格納する

メモリに値を格納するための決定事項

どの位置を使うか

何バイト分を使うか

値をどのように表現するか

これを決めるのが変数という機能

40

2014 -3.14159 'C' '言'

Page 39: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

とりあえず、変数定義の例

違いをよく観察

41

#include <stdio.h>

int main(void)

{

int x = 150;

printf("%d¥n", x);

printf("%d¥n", x*2);

return 0;

}

150

300

150

x という名前が付けられているx

位置は自動的に決まる式の中では 150 と評価される

int は整数のための変数

記録されている値

Page 40: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

変数の型

int

整数を格納する

整数は英語で integer という

double (float)

実数(浮動小数点数)を格納する

内部表現が倍精度実数と呼ばれるため

char

1 バイトを格納する

主に文字列を扱う際に使う

character が語源

42

Page 41: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

変数定義の別の例

変数は複数定義できる。

43

#include <stdio.h>

int main(void)

{

int x = 150;

double y = 20;

printf("%f¥n", x+y);

return 0;

}

170.000000

150

x

変数ごとにメモリ上の場所が違う

計算結果はdouble 型になので, %f で表示する

20.0

y

Page 42: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

int 型は整数値を表現

以下の修飾が可能

サイズ: short / long / 未修飾

• [C99 以降] long long

符号の有無: signed / unsigned

• 省略した場合は signed と同じ

型のサイズは処理系依存

採用するサイズの組み合わせ=データモデル

64 bit 環境だと Linux (LP64) と Windows (LLP64) で異なる

整数型 (integer) 44

C89 といった規格書では具体的に定義されていないということ。従って、自分が使う環境ではどうなっているかを知っておかなければならない。

Page 43: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

浮動小数点型 (floating point)

float 型, double 型は小数を表現

実数型とも呼ばれるが数学用語の実数とは異なる

精度(有効桁数)が異なる

非常に大きな数から小さな数まで表現できる

±𝑎 ⋅ 2𝑏 という形式で保持している

𝑎, 𝑏 の範囲に制限があるので、どんな数でも表せるわけではない

• たとえば 0.1 は表現できないのでそれに近い近似値が使われる

45

特殊なCPUを除いて IEEE754 という規格の表現が使われる

0.1 を 10 回足し合わせる計算をさせても 1 にならない

Page 44: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

整数型の一覧

型名(赤字以外省略可能)

サイズ (bit) その値の範囲(LP64 の場合)

ILP32 LP64 LLP64

signed short int 16 16 16 −32768 ~ + 𝟑𝟐𝟕𝟔𝟕

unsigned short int 0 ~ 𝟔𝟓𝟓𝟑𝟓 (= 216 − 1)

signed intsigned int

32 32 32 −231 ~ 231 − 1(±𝟐𝟎億ぐらい)

unsinged int 0 ~ 𝟒𝟎億ぐらい

signed long int 32 64 32 ±9 × 1018 ぐらい

unsigned long int 0 ~ 1.9 × 1018 ぐらい

46

Windows 64bitLinux 64bit32bit OS

データモデル

規格では short ≦ int ≦ long とだけ定められている

キーワードの順番は任意

Page 45: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

浮動小数点型の一覧

型名 一般名 サイズ

(bit)

その値の範囲と精度

float 単精度実数 32 ±3.4 ⋅ 10±38, 7 桁程度

double 倍精度実数 64 ±1.7 ⋅ 10±308, 15 桁程度

long double(C99 以降)

拡張倍精度実数 80~128(処理系で異なる)

47

表現する値の絶対値の大きさだけでなく、その精度(桁数)も異なることに注意。 double のほうがより精度が高い。

IEEE754 の場合

C99 以降では複素数型が追加されたので実浮動小数点型と呼んでいる

double は float の値を完全に表現することができる

Page 46: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

文字型 (character)

char 型は 1byte の整数を表現

8bit 以上であると規定されている

ここでは 8bit と仮定

「文字」型と呼ばれるのは、英数字をすべて表すのによくつかわれるから

符号付きかどうかの修飾によって以下の3通りの書き方がある (種類は 2 つしかない)

char: 以下のどちらと同じ意味かは処理系依存

signed char: 符号付き (−127~128)

unsigned char: 符号無し (0~255)

48

gcc など多くの処理系が signed としている

Page 47: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

ASCII コード

英数・記号を 1byte で表す一般的なコード

American standard code for information interchange の略

日本語用の文字コードでも利用

日本語用のキーボード (OADG 106/109)

では、このコード順に記号が並んでいる

49

0 1 2 3 4 5 6 7

0 0 @ P ` p

1 ! 1 A Q a q

2 " 2 B R b r

3 # 3 C S c s

4 $ 4 D T d t

5 % 5 E U e u

6 & 6 F V f v

7 ' 7 G W g w

8 ( 8 H X h x

9 ) 9 I Y I y

A * : J Z j z

B + ; K [ k {

C , < L ¥ l |

D - = M ] m }

E . > N ^ n ~

F / ? O _ o

この表は縦横で2桁の16進数を表している覚える必要はない

Page 48: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

関数が呼ばれると

1. メモリに変数領域を確保

2. 初期化

3. 関数本体の実行

50変数定義の結果

...

int main(void)

{

int x;

int y, z;

int number = 5;

float Data_1;

double Data_2;

char ch = 'C';

printf(...

... 関数の本体

??

x

??

y

??

z

5

number

??

Data_2 ??

Data_1

C

ch

メモリに変数が確保された様子メモリ上では連続して変数が並ぶとは限らないので、帯の絵はかいていない

Page 49: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

初期値を与えない変数の内容は不定

もともとメモリに何が入っているかはわからない

0 であるとは限らない

「空っぽ」という概念はない この性質を悪用されると、システムに重大な被害を与えてしまうかもしれない。こういう問題をセキュリティホールという。

51変数の初期値

...

int main(void)

{

int x;

double f;

...??

x

??

f

もしかしたら -82 が入っているかもしれない

プログラムを実行するたびに違う値が入っているかもしれない

Page 50: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

普通の整数を使いたい場合

int

特に負の値にならないことをはっきりさせたい場合は

unsigned int

short はめったに使われない

long は Windows 環境では int と同じなので、大きな数が扱えると期待すると互換性に問題がある

小数の値を入れようとすると、自動的に切り捨てられる

52どの型を使えばいいの? (1/3)

メモリ上のサイズなどを表すには、 size_t が使われる。これは、無符号整数であり、メモリのサイズを十分表すことができる型である。

Page 51: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

小数点を含む数値を扱いたい場合

double

特にメモリ使用量の制約がある場合は float

float は一度 double に変換されて計算に使われるため、保存形式としてのみ意味がある

これらの型は正確に数値を表現していない可能性があることに注意

53どの型を使えばいいの? (2/3)

Page 52: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

文字列を扱う場合

char

文字列の詳細は次回以降

8bit 単位で意味を持たせた情報(画素値など)を扱う場合

unsigned char

純粋にビット列を扱うために符号などの処理をされないようにする

54どの型を使えばいいの? (3/3)

Page 53: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

代入 (assignment)

代入演算子によって変数の内容を書き換えること

変数の初期化と似ているが、区別されている

55

#include <stdio.h>

int main(void)

{

double x = 15, y = 10, s, m;

s = x + y;

m = s / 2.0;

...

x, y を初期化

15

x

10

y

??

s

??

m

s, m を式の評価値で置き換える(=代入)

Page 54: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

代入演算子

a = 7 (変数 a の値を 7 に書き換える)

x = (複雑な式)

• 式の結果を x に代入する

基本的な演算子 (operators) 56

Page 55: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

インクリメント・デクリメント

a++ ++a

a-- --a

基本的な演算子 (operators) 57

変数の値を 1 増加する

後置の評価値は変更前の値、前置は変更後の値

変数の値を 1 減少する

後で学習するループ制御で多用する

Page 56: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

複合代入演算子

演算と代入を同時に行う

a += 7 a = a + 7 と同じ

-= *= /= %=

&= |= ^=

<<= >>=

58

記号の順番に注意

Page 57: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

式の評価 (evaluation)

演算子の計算を行うこと、関数の呼び出しをすることなどで、値を計算することを評価 (evaluation) という

59

s = (x + 2) * 2;

⇓ (変数の評価)

s = (5 + 2) * 2;

⇓ (+ 演算子の評価)

s = 7 * 2;

⇓ (/ 演算子の評価)

s = 14;

⇓ (代入演算子の評価)

14;14

s

5

x

最後の評価値は捨てられる

代入で書き換えられる

代入演算も評価値を持つ

s

関数の呼び出しも演算子の一種

Page 58: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

演算の順序

どの演算子から演算を行うかは優先順位と結合方向で決まっている(詳しくはリファレンス参照)

優先順位

異なる演算子の演算順番

おおよそ数学の用法に近いが、一部は直観と反する

結合方向

同じ演算子、または優先順位が同じ演算子の順序

a+b+c は (a+b)+c (左から右) となるなど

60

Page 59: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

代入演算について

代入演算子はその代入された値を評価値として持つ

代入演算子を複数つなげて、連続した代入を行うことができる

x = y = 5;

x = (y = 5); 右から左への結合

x = 5; 代入演算子の評価により 5

61

Page 60: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

printf() も評価値を持っている

printf も値を返す関数である

普段はあまり利用されず、単に無視されている

62

printf("Hello, world!¥n");

⇓ (printf 関数の評価)

14;

Hello, world!

標準出力

出力された文字数が返されるが、この場合、特にそれを使っていないので、そのまま捨てられる

Page 61: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

除算演算子の注意

int 同士の除算は結果が切り捨てられて int になる

63

int x = 5, y = 2;

double z;

z = (x + y) / 2;

⇓ (変数の評価)

z = (5 + 2) / 2;

⇓ (+ 演算子の評価)

z = 7 / 2;

⇓ (/ 演算子の評価)

z = 3;

int x = 5, y = 2;

double z;

z = (x + y) / 2.0;

z = (5 + 2) / 2.0;

z = 7 / 2.0;

z = 3.5;

整数リテラル 浮動小数点リテラル

結果が整数となった

少なくとも一方がdouble なら結果はdouble になる

Page 62: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

値の表示

64

Page 63: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

printf() は書式を指定して文字列を出力する関数

書式文字列は % が特別な意味を持っている

65printf() で数値を表示する

#include <stdio.h>

int main(void)

{

printf("%d¥n", 5);

...

printf() を使うために必要。スタジオではない。

Standard Input/Output

変数と関数を区別するために、よく括弧を付けて表記される

書式文字列

%d が数値5 をどのように表示するかを指定している

表示しようとする値をカンマで区切って指定

Page 64: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

printf() はとても複雑です

すべてを覚える必要は全くありません

使いたいときに、参考資料を基に調べられるようになればよい

資料はインターネット・書籍でたくさんあります

今日はほんの一例を紹介します

66printf() の心得

ちなみに、 printf の f は、書式 (format) という意味です

Page 65: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

文字列はそのまま画面に出力される

ただし、 % を表示するには %% とする

¥n は改行を表す

67printf() の例 (1)

printf("Hello, World%%¥n");

Hello, World%

改行を表す

カーソル位置が次に行に移動している

% に置き換わる

Page 66: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

%d, %i は符号付き 10 進整数に置き換わる

68printf() の例 (2) 整数

printf("Year:%d.¥n", 2015);

Year:2015.

整数を 10 進数で表示する指定

%d が 2015 に置き換わっているそれ以外はそのまま文字を表示

表示したい整数%d と %i は同じ意味です

無符号整数の場合は %u を用います。

Page 67: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

リテラルの種類とは関係ない

69printf() の例 (2.1) 整数

printf("Year:%d!¥n", 0x07df);

Year:2015!

整数を 10 進数で表示する指定

%d が 2015 に置き換わっている

表示したい整数

Page 68: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

%x, %X は 16 進数に置き換わる

70printf() の例 (2.2) 整数

printf("Year:%X!¥n", 0x07df);

Year:7DF!

整数を 16 進数大文字で表示する指定

桁数は指定されていないので、最小になる

表示したい整数

%o, %O は 8 進数に置き換わります。

表示が大文字小文字の違い

Page 69: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

出力幅 (文字数) は % の直後に書く

空白か 0 がつめられる (padding)

71printf() の例 (2.3) 幅

printf("Year:%8X!¥n", 2015);

printf("Year:%08X!¥n", 2015);

Year: 7DF!

Year:000007DF!

整数を 16 進数大文字8桁で表示する指定

空白が 5 つ空いて、全体で 8 文字

0 が前に詰められている

0 詰め (zero padding) をする場合

Page 70: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

%f は浮動小数点型の値を変換する

72printf() の例 (3) 小数

printf("%f¥n", 0.1);

0.100000

小数点表示を指定する

桁数が指定されていない場合、 6 桁となる

表示したい浮動小数点数

%f は double 型の値に対応しています。しかし、 float 型のための指定はありません。なぜなら、 float は必ず double に変換されてから関数に渡されるためです。

Page 71: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

精度 (小数点以下の桁数) は %.10f の様に指定する

73printf() の例 (3.1) 小数の精度

printf("%.10f¥n", 0.1);

0.1000000000

小数点以下 10 桁の表示を指定する

桁数が指定されて 10 桁で表示される

ピリオドの位置に注意

Page 72: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

%e, %E は指数形式の文字列に置き換わる

74printf() の例 (3.2) 指数形式

printf("%e¥n", 0.1);

1.000000e-01

▮1.0 × 10−1 という意味

%g, %G は、小数点表示、指数表示のうち、短い方を採用する

指数を表す e の大文字小文字が異なります

Page 73: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

複数回 % を書くと, 順番に変換される

75printf() の例 (4) 複数表示

printf("%04d/%02d/%02d¥n", 2015, 4, 20);

2015/04/20

複数書くと、順番に変換される

% 書式の数だけカンマで区切って指定

指定する数値の数が足りない場合, 動作は未定義指定する数値の数が多い場合は、書式文字列が繰り返し使われます

Page 74: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

変数名を書けば、その値が使われる

計算式を書くこともできる

76printf() で変数表示

#include <stdio.h>

int main(void)

{

int year = 2015;

printf("This year %04d¥n", year);

printf(“Next year %04d¥n", year + 1);

return 0;

}

変数名はその保持する値に置き換わる

This year 2015

Next year 2016

2015+1 が計算される

2015

2016

次回詳しく説明

Page 75: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

%d で表示できるのは int 型

%f で表示できるのは double 型

型を変えるにはキャストを使う

77printf() で変数表示する際の注意

#include <stdio.h>

int main(void)

{

int val = 2015;

printf("%d %f¥n", val, val);

return 0;

} 2015 0.000000

int の値を %f で正しく表示できない

今後説明

Page 76: 02: C 言語の基礎...C 言語の歴史1973 年、それまで機械語で書かれていたUNIX の開発を簡 単にするためにAT&T 研究所のDennis Ritchie が開発 すでにつくられていたB言語を改良

他にも説明していないことはたくさんありますが、インターネットや書籍の参考資料で勉強してください

少なくとも、レポート課題など必要な情報はそのたびに提供します

78printf() のまとめ