PowerPoint

C プログラミング入門
基幹7 (水5)
03: 変数と標準入出力
Linux にログインし、以下の講義ページ
を開いておくこと
http://www-it.sci.waseda.ac.jp/
teachers/w483692/CPR1/
2016-04-20
1
今日の内容
変数と型
リテラル
整数型
整数
標準入出力
printf()
浮動小数点数
浮動小数点型
文字
文字型
文字列
scanf()
2
メモリの概念図
前後に続いている
たとえば 00110110 といった状
態列(ビット列)を持っている
メモリ: 0/1 の状態を大量に保持する装置
この講義で用いるメモリの概念図
1本の帯で表現し、その帯の一部分を見ている
連続する bit 列を 8bit (=1byte) ずつ区切る
何も書かれていないマスも必ず何かの状態を保持
していることに注意
3
メモリに値を格納する
2014
-3.14159
'C'
'言'
メモリに値を格納するために決めること
どの位置を使うか
何バイト分を使うか
値をどのように表現するか
これを決めるのが変数という機能
4
とりあえず、変数定義の例
Hello world との違
いを観察
位置は自動的に決まる
x
x という名前が
付けられている
#include <stdio.h>
int main(void)
{
int x = 150;
150
printf("%d\n", x);
int は整数のた
めの変数
150
▮
記録されている値
return 0;
}
5
変数 (variable)
メモリの一部分に名前を付加
名前は自分で自由に指定可能
数学用語の変数とは意味が異なる
メモリを使う場所は自動的に決定される
1つの値を保存
保存する値の種類を型 (type) という
• メモリ上で占める大きさ(サイズ)
• ビット列が表す値の意味とその範囲
値は変更しない限り変わらない
6
変数の定義
変数定義の構文
型名 変数名 [ = 初期値 ];
位置は自動的に決まる
x という名前が
付けられている
x
#include <stdio.h>
int main(void)
ブロックの始り
{
int x = -2;
変数名
printf("%d\n", x);
変数の型
-2
return 0;
サイズは型に
よって決まる
値
}
7
変数定義の書き方
変数定義はブロックの先
頭でのみ可能
初期化(初期値を書くこ
と)をしてもよい
初期値を表す数値をソース
コード上で書く方法をリテ
ラルという(後述)
同じ型の変数名をカンマ
(,) で区切って複数並べ
てもよい
ブロックの先頭
...
int main(void)
{
int x;
int y, z; 初期値の指定
int number = 5;
float Data_1;
double Data_2;
char ch = 'C';
初期値の指定
printf(...
...
関数の本体
8
変数名 (variable name)
変数の名前は自由に付けてよい
変数につける名前には以下のルールがある
英数字 (A-Z, a-z, 0-9) とアンダースコア (_) の1
文字以上の組み合わせ
最初の一文字は数字使用不可
予約語 (キーワード) と同じであってはならない
大文字小文字は区別される (case strict)
規格上は長さの制約はない
が、せいぜい 30 文字程度
そのほか、ダブルアン
ダースコアで始まる名前
は禁止されているなど細
かい規定がありますが、
省略します
9
変数の型 (variable type)
変数に格納できる値の種類を表すもの
基本型には以下の3つがある このあと説明
整数型 (int)
文字型 (char)
浮動小数点型 (float, double)
それ以外
C99 以降では、複素数
型 _Complex が規定さ
れたがこの講義では扱
わない
今後の回で説明(一部のみ)
列挙体 / 列挙型
派生型
• 集成体型 (構造体, 配列), 共用体, 関数, ポインタ
10
計算とリテラル
数値の計算を行うコードを式 (expression)
という
式ではリテラル (定数)・演算子・変数名・関
数呼び出しを使うことができる
式の例
30 – (radius * radius * 3.14)
演算子
整数リテラル
演算子
変数名
浮動小数点リテラル
変数名
演算子
演算子
演算子
11
定数・リテラル (constant, literal)
ソースコード上に書かれた数値などのこと
たとえば、 5 とか 0.3 とか
規格では、文字列以外は定数とよび、文字列のみ
文字列リテラルと呼んでいる
書き方が複数ある
それぞれに合わせた数値の型を持つ
C 言語特有の書き方がいくつかあるので覚え
literal は文字通りの
てください
という意味
12
整数型
13
整数リテラル
正確には符号はリテラルの
一部ではなく演算子
10進数
0
+2013
100
-30
2014
型は、その値を表現できる
最小の整数型となる
明示的に型を指定する接尾
辞を付加することもできる
がここでは省略する
16進数: 0~9, A~F で表現
0x1A 26
8進数
07
7
0x001A 26
0x07de
2014
0xFFFF
65535
0 を前に追加してよい
012
10
リテラルではないもの(エラーとなる)
☠08
8 進数では 8 は使わない
10 進数に 0 を追加したものとはみなされない
14
整数型 (integer)
int 型は整数値を表現
以下の修飾が可能
サイズ: short / long / 未修飾
• [C99 以降] long long
符号の有無: signed / unsigned
• 省略した場合は signed と同じ
型のサイズは処理系依存
C89 といった規格書
では具体的に定義さ
れていないというこ
と。従って、自分が
使う環境ではどう
なっているかを知っ
ておかなければなら
ない。
採用するサイズの組み合わせ=データモデル
64 bit 環境だと Linux (LP64) と Windows
(LLP64) で異なる
15
整数型の一覧
データモデル
型名
(赤字以外省略可能)
signed short int
サイズ (bit)
ILP32
16
LP64 LLP64
16
その値の範囲
(LP64 の場合)
16
0 ~ 𝟔𝟓𝟓𝟑𝟓 (= 216 − 1)
unsigned short int
32
signed int
signed int
−32768 ~ + 𝟑𝟐𝟕𝟔𝟕
32
32
−231 ~ 231 − 1
(±𝟐𝟎億ぐらい)
0 ~ 𝟒𝟎 億ぐらい
unsinged int
signed long int
32
64
32
0 ~ 1.9 × 1018 ぐらい
unsigned long int
32bit OS
±9 × 1018 ぐらい
Linux 64bit
Windows 64bit
規格では short ≦ int ≦ long とだけ定められている
キーワードの順番は任意
16
文字型
17
文字リテラル・文字列リテラル
文字: 文字を表すコードになる
'a'
'\n'
型は char ではなく
int である。
'C'
特殊な文字を表すためにバックスラッシュを使うことがある
リテラルではないもの(エラーとなる)
☠'abc'
文字リテラルは 1 文字しかかけない
文字列リテラルとの違いに注意
"Hello, world\n"
文字列リテラルを char 型変数に入れること
はできない
型は char * (char へのポイン
タ) である。詳細については文字
列の回で説明
18
文字型 (character)
char 型は 1byte の整数を表現
8bit 以上であると規定されている
ここでは 8bit と仮定
「文字」型と呼ばれるのは、英数字をすべて
表すのによくつかわれるから
符号付きかどうかの修飾によって以下の3通り
の書き方がある (種類は 2 つしかない)
char: 以下のどちらと同じ意味かは処理系依存
signed char: 符号付き (−127~128) gcc など多くの処
理系が signed と
unsigned char: 符号無し (0~255) している
19
ASCII コード
英数・記号を 1byte で表す一
般的なコード
American standard code for
information interchange の略
日本語用の文字コードでも利用
日本語用のキーボード (OADG
106/109) では、このコード順に記
号が並んでいる
この表は縦横で2桁の16
進数を表している
覚える必要はない
0
1
2
0
3
4
5
6
7
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
20
浮動小数点型
21
浮動小数点リテラル
小数
3.14
1.
.5
-.3
型は、接尾辞で明示的に
指定しない限り double
となる
指数表現(科学技術形式)
6.02e23 6.02 × 103
1E3 1.0 × 103
314e-2 314 × 10−2 = 3.14 ただし、 3.14 がメモリ表現として正
確に表せるかどうかは別問題である
2.3e-04
通常は近似値である(前述)
22
浮動小数点型 (floating point)
float 型, double 型は小数を表現
実数型とも呼ばれるが数学用語の実数とは異なる
精度(有効桁数)が異なる
非常に大きな数から小さな数まで表現できる
±𝑎 ⋅ 2𝑏 という形式で保持している
𝑎, 𝑏 の範囲に制限があるので、どんな数でも表せ
るわけではない
• たとえば 0.1 は表現できないのでそれに近い近似値が
使われる
0.1 を 10 回足し合わせる計算を
させても 1 にならない
特殊なCPUを除いて IEEE754 と
いう規格の表現が使われる
23
浮動小数点型の一覧
型名
一般名
サイズ
(bit)
その値の範囲と精度
float
単精度実数
32
±3.4 ⋅ 10±38 , 7 桁程度
double
倍精度実数
64
±1.7 ⋅ 10±308 , 15 桁程度
long double
拡張倍精度実数 80~128
(処理系で
異なる)
(C99 以降)
IEEE754 の場合
表現する値の絶対値の大きさだけ
でなく、その精度(桁数)も異な
ることに注意。 double のほうが
より精度が高い。
double は float の値を完全に表現することができる
C99 以降では複素数型が追加されたので実浮動小数点型と呼んでいる
24
変数の利用
25
変数定義の結果
関数が呼ばれると
1.
2.
3.
z
??
ch
C
...
int main(void)
メモリに変数領域を確保
{
初期化
int x;
関数本体の実行
int y, z;
メモリに変数が確保された
int number = 5;
様子
number
メモリ上では連続して変数 float Data_1;
5
が並ぶとは限らないので、
double Data_2;
帯の絵はかいていない
y
x
char ch = 'C';
??
??
Data_1
??
printf(...
Data_2
...
関数の本体
??
26
変数の初期値
初期値を与えない変数の内容は不定
もともとメモリに何が入っているかはわからない
0 であるとは限らない
「空っぽ」という概念はない
 この性質を悪用されると、システムに重大な被害を与えてしまうかもしれない。
こういう問題をセキュリティホールという。
...
int main(void)
{
int x;
double f;
...
もしかしたら -82
が入っているかも
しれない
プログラムを実行する
たびに違う値が入って
いるかもしれない
f
x
??
??
27
どの型を使えばいいの? (1/3)
普通の整数を使いたい場合
int
特に負の値にならないことをはっきりさせたい場
合は unsigned int
short はめったに使われない
long は Windows 環境では int と同じなので、
大きな数が扱えると期待すると互換性に問題がある
小数の値を入れようとすると、自動的に切り捨て
られる
メモリ上のサイズなどを表すには、 size_t が使われる。これは、無符号整
数であり、メモリのサイズを十分表すことができる型である。
28
どの型を使えばいいの? (2/3)
小数点を含む数値を扱いたい場合
double
特にメモリ使用量の制約がある場合は float
float は一度 double に変換されて計算に使われ
るため、保存形式としてのみ意味がある
これらの型は正確に数値を表現していない可能性
があることに注意
29
どの型を使えばいいの? (3/3)
文字列を扱う場合
char
文字列の詳細は次回以降
8bit 単位で意味を持たせた情報(画素値な
ど)を扱う場合
unsigned char
純粋にビット列を扱うために符号などの処理をさ
れないようにする
30
値の表示
31
printf() で数値を表示する
printf() は書式を指定して文字列を出力す
変数でなく関数であることを明示するために括弧を付けている
る関数
printf の f は書式 (format) の意味
書式文字列は % が特別な意味を持っている
書式文字列
%d が数値
5 をどのよ
うに表示す
るかを指定
している
printf() を使うために必要。
スタジオではない。
Standard Input/Output
#include <stdio.h>
int main(void)
{
printf("%d\n", 5);
...
表示しようとする値をカ
ンマで区切って指定
33
printf() の心得
printf() はとても複雑です
すべてを覚える必要は全くありません
使いたいときに、参考資料を基に調べられるよう
になればよい
資料はインターネット・書籍でたくさんあります
今日はほんの一例を紹介します
ちなみに、 printf の f は、書式 (format) という意味です
34
printf() の例 (1)
文字列はそのまま画面に出力される
ただし、 % を表示するには %% とする
printf("Hello, World%%\n");
% に置き換わる
改行を表す
Hello, World%
▮
カーソル位置が次に行に移動している
35
printf() の例 (2) 整数
%d, %i は符号付き 10 進整数に置き換わる
表示したい整数
%d と %i は同じ意味です
printf("Year:%d.\n", 2015);
整数を 10 進数で表示
する指定
Year:2015.
▮
%d が 2015
に置き換わっている
それ以外はそのまま文字を表示
無符号整数の場合は %u を用います。
36
printf() の例 (2.1) 整数
リテラルの種類とは関係ない
表示したい整数
printf("Year:%d!\n", 0x07df);
整数を 10 進数で表示
する指定
Year:2015!
▮
%d が 2015 に置き換わっている
37
printf() の例 (2.2) 整数
%x, %X は 16 進数に置き換わる
表示したい整数
表示が大文字小文字の違い
printf("Year:%X!\n", 0x07df);
整数を 16 進数大文字
で表示する指定
Year:7DF!
▮
桁数は指定されていないので、最小になる
%o, %O は 8 進数に置き換わります。
38
printf() の例 (2.3) 幅
出力幅 (文字数) は % の直後に書く
空白か 0 がつめられる (padding)
整数を 16 進数大文字
8桁で表示する指定
printf("Year:%8X!\n", 2015);
printf("Year:%08X!\n", 2015);
0 詰め (zero padding)
をする場合
Year:
7DF!
Year:000007DF!
空白が 5 つ空いて、全体で 8 文字
0 が前に詰められている
39
printf() の例 (3) 小数
%f は浮動小数点型の値を変換する
表示したい浮動小
数点数
printf("%f\n", 0.1);
小数点表示を指定する
0.100000
▮
桁数が指定されていない場合、 6 桁となる
%f は double 型の値に対応しています。しかし、 float 型のための指定はありま
せん。なぜなら、 float は必ず double に変換されてから関数に渡されるためです。
40
printf() の例 (3.1) 小数の精度
精度 (小数点以下の桁数) は %.10f の様に指
定する
printf("%.10f\n", 0.1);
ピリオドの位置に注意
小数点以下 10 桁の表
示を指定する
0.1000000000
▮
桁数が指定されて 10 桁で表示される
41
printf() の例 (3.2) 指数形式
%e, %E は指数形式の文字列に置き換わる
指数を表す e の大文字小文字が異なります
printf("%e\n", 0.1);
1.000000e-01
▮
1.0 × 10−1 という意味
%g, %G は、小数点表示、指数表示のうち、短い方を採用する
42
printf() の例 (4) 複数表示
複数回 % を書くと, 順番に変換される
printf("%04d/%02d/%02d\n", 2015, 4, 20);
複数書くと、順番に変
換される
2015/04/20
▮
% 書式の数だけカンマ
で区切って指定
指定する数値の数が足りない場合, 動作は未定義
指定する数値の数が多い場合は、書式文字列が繰り返し使われます
43
printf() で変数表示
変数名を書けば、その値が使われる
計算式を書くこともできる 次回詳しく説明
#include <stdio.h> 変数名はその保持する値に置き換わる
int main(void)
2015+1 が計算される
{
int year = 2015;
printf("This year %04d\n", 2015
year);
printf(“Next year %04d\n", year
2016+ 1);
return 0;
This year 2015
}
Next year 2016
44
printf() で変数表示する際の注意
%d で表示できるのは int 型
%f で表示できるのは double 型
型を変えるにはキャストを使う
#include <stdio.h>
int main(void)
{
int val = 2015;
printf("%d %f\n", val, val);
return 0;
}
今後説明
int の値を %f で正し
く表示できない
2015 0.000000
45
printf() のまとめ
他にも説明していないことはたくさんありま
すが、インターネットや書籍の参考資料で勉
強してください
少なくとも、レポート課題など必要な情報はその
たびに提供します
46
scanf()
標準入力から読んだ値を変数に書き込む関数
scanf() は printf() よりもっと難しいです
以下の定型的な書き方を覚えてください。
#include <stdio.h>
int main(void)
{
int x; float y; double z;
scanf("%d", &x);
scanf("%f", &y);
scanf("%lf", &z);
イチではなくエル
...
必ず & という文字が必要
int 型変数には %d
float 型変数には %f
double 型変数には %lf
47
scanf() について
scanf() は、値の取り扱いに重大な欠陥があ
るため、実用的なプログラムではめったに使
われませんし、また使うべきではありません
深刻なセキュリティホールになりえます
ただし、キーボードから値を読み込む簡単な
手段なので、講義では最小限の利用をします
より良い入力方法については以下のサイトが
参考になります
 http://www.6809.net/tenk/html/cgokai/scanf.htm
 http://www.6809.net/tenk/html/cgokai/gets.htm
48