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
© Copyright 2024 ExpyDoc