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