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