/* * 課題 CNAME-03 * * 20200918 20200918-03-QQQQ.c * * printf の書式指定 * */ #include <stdio.h> /* * */ /* * main */ int main( int argc, char *argv[] ) { int ia = 7; int ib = 15; double da = 3.14; double db = 1.59; /* 二つの整数値 ( 変数 ia, ib ) の和を出力 */ /* => 7 + 15 = 22 */ printf ( "%d + %d = %d\n", ia, ib, ia + ib ); /* 整数型の和 */ /* 二つの浮動小数点数値 ( 変数 da, db ) の商を出力 */ printf ( "%f / %f = %f\n", da, db, da / db ); /* 浮動小数点数の商 */ /* 書式は、出力したい値の型によって、異なる 整数値 => %d 浮動小数点数値 => %f */ return 0; }
/* * 課題 CNAME-04 * * 20200918 20200918-04-QQQQ.c * * scanf の書式指定 * */ #include <stdio.h> /* * */ /* * main */ int main( int argc, char *argv[] ) { int i; /* キーボードから入力された整数値を保持する整数型変数 */ double d; /* キーボードから入力された浮動小数点数値を保持する浮動小数点数型変数 */ printf ( "整数値をキーボードから入力します : " ); scanf ( "%d", &i ); printf ( "入力された整数値は %d でした。\n", i ); printf ( "浮動小数点数値をキーボードから入力します : " ); scanf ( "%lf", &d ); /* 浮動小数点数の場合 f でなく lf */ printf ( "入力された浮動小数点数値は %f でした。\n", d ); return 0; }
#include <stdio.h> int main(void) { printf ( "Hello, World\n" ); return 0; }
#include <stdio.h> int main(void) { printf ( "整数値の出力例 (%d) \n", 123 ); return 0; }
#include <stdio.h> #include "s_print.h" int main(void) { /* printf ( "整数値の出力例 (%d) \n", 123 ); */ s_print_string ( "整数値の出力例 (" ); s_print_int ( 123 ); s_print_string ( ") \n" ); return 0; }
#include <stdio.h> #include "s_print.h" void my_func ( char *var_name, int num ) { s_print_string ( var_name ); s_print_string ( "=" ); s_print_int ( num ); s_print_string ( "\n" ); } int main(void) { my_func ( "x", 123 ); my_func ( "var", 456789 ); /* my_func ( "x", 1, -1 ); 気持ちは x の値が +- 1 の二つの値を持つ事を表したい けど、 ダメ ( 関数の引数と型は、関数宣言時に決まっている ) */ return 0; }
#include <stdio.h> int main(void) { int a = 123; /* 整数型変数 a を宣言し 123 で初期化 */ double b = 1.23; /* 浮動小数点数型変数 b を宣言し 1.23 で初期化 */ /* 二つの(型の異なった) 変数の値を一挙に出力 */ printf ( "int a=%d, double b=%f\n", a, b ); return 0; }
#include <stdio.h> int main(void) { int a; int b; printf ( "整数型変数 a の値を入力してください = " ); scanf ( "%d", &a ); /* 書式指定は、書式一つで、型に合わせる ); /* 変数の前に「&」を付ける */ printf ( "整数型変数 b の値を入力してください = " ); scanf ( "%d", &b ); printf ( "%d と %d の和は %d です。\n", a, b, a + b ); return 0; }
整数値をキーボードから入力します : 入力された整数値は 123 でした。 浮動小数点数値をキーボードから入力します : 入力された浮動小数点数値は 1.230000 でした。
前回の内容 命令 C 言語で、「何か(直接)する」記述 関数呼び出し ( printf ) return 命令 ( 関数を途中で終了し、値を返す ) 構文 : 命令を組み合わせて、新しい命令を作る表現 if 構文 条件によって、二つの命令の一方を実行する 代入 構文 : 「変数名」=「式」; 例 : i = 1+2; <= 変数 i に値 1+2 の結果である 3 を代入する命令 !! 「式」を書くと、「その式に従って値を計算する」 !! => 高級言語 ( Fortaran ; Formular Translator : 式を変換する ) !! 1 + 2 * 3 => 1 + 6 => 7 意味 : 「変数(変数名によって指定された)」に、 「式」を「計算した結果(式の値)」の「値」(求めて、それ)を「割り当てる命令」 代入の効果 : 変数の値が変化 ( 変化するものだから変数 ) 代入前と代入後では変数の値が異る ( 「前」と「後」という「時間」の変化 ) (代入された変数を含む)「同じ」命令が、 (その値が変化する事により)「異る」振舞いをする # 関数の効用 # 関数定義を行い、実引数を変更して関数呼び出しをすると # (同じ関数定義でも..) 異なる振る舞いができる # !! 実引数の指定 => 関数定義の仮引数変数への代入 # 変数(群)の値の変更を行いながら、 # (変数の値にした違った)命令の実行を与わせる # 手続き型言語の特徴 関数の仮引数変数 => 変数の一つ => 代入可能 居所変数 ( local variable, auto 変数 ) 1. 本体のブロックの先頭に変数宣言すると、関数内で使える 2. 最初はどんな値になっているかわからない => 必ず、値を代入してから使う必要がある !! 仮引数変数 <= 実引数の値で初期化されている !! => すぐに利用できる 「局所変数の値を定めずに、利用する(初期化忘れ)」 => 典型的なミス(気を付ける) 標準 I/O ライブラリの利用 標準 I/O ライブラリ I/O とは Input(入力) と Output(出力) の事 Input : プログラムが、プログラムの外から、 情報を読み込む(Read) Output : プログラムが、プログラムの外へ、 情報を書き出す(Write) [ポイント] 「外」はプログラムの置かれている環境で異る (i.e OS) !! 普段 : 「外」<=> 「人間」 (man machine interface) !! Program !! <= OS <= キーボード <= 人間 (Input) !! => OS => ディスプレイ => 人間 (Output) 「外」が違う 「同じ目的の事」が、「異なる手段」 例 : 「あいさつ」をするとき 日本とアメリカで異るの嫌 (だから全て英語で.. それも困るが..) +-A-> Windows Program +--+ +-B-> Ubuntu +-(Z=>A) -A-> Windows Program +--Z---+ +-(Z=>B) -B-> Ubuntu 標準ライブラリ 環境(外)の違いを吸収する役割 標準ライブラリを学び、利用する => 一つの表現を覚えれば、 色々な環境で、それが使える その違いを標準ライブラリが吸収してくれる 標準 I/O ライブラリの役割 異る環境でも、プログラムとしては、 同じ方法で I/O を行うための仕組 環境の違いはライブラリが吸収 (挨拶は手を振るで OK) 標準 I/O ライブラリの機能 I/O する物 : 文字、文字列、数値(基本データ) I/O の相手先 : キーボード(I), ディスプレイ(O),ファイル(I/O) printf の秘密 printf -- 引数で与えた文字列を画面に表示する printf : 超高機能出力関数 print with format (書式付き出力) 単なる文字列出力関数ではなかった ( cf. s_print_string : 単機能 ) 最初の引数に「『書式』を指定する文字列」を指定し、 書式に従って、二つ目以後のデータを(適切に整形して)出力する 書式 「書式('%' + 書式指示)」を指定する事により 何(基本型+文字列)が出力できる 例: %d 整数値を出力する %f 浮動小数点数値を出力する %s 文字列を出力する printf の利用の具体例 printf ( "整数値は (%d) です。\n", 123 ); => 「整数値は (123) です。」+「改行」 ^^^ 書式指定の %d の所が、その後の引数である「123」に置き換わる => 様々なデータ(型)が混在する出力を、簡単に書ける !! 引数の個数が変わる !! 引数の型も変わる !! => どうやって実現しているのか ? !! !! (現状で学んでいる)関数定義では、 !! !! 引数の個数も型も固定(定義時に決めたもの)になる printf ( "%f", 1.23 ); printf ( "%c", 'a' ); printf ( "%s", "abc" ); 文字列の中に出力を埋め込む事ができる int a=123; printf ( "int a=%d;\n", a ); => 複数のデータの出力が混在している場合でも、 簡単に実現できる ( cf. s_print.h と比較 ) 複数のデータを一度に出力する事ができる 書式は、書式指定文字列の中に、複数指定できる 書式指定文字列の後に、書式の個数だけ、値を指定して、 一挙に複数の値が出力できる int a=123; double b=1.23; printf ( "int a=%d, double b=%f\n", a, b ); ^^(1) ^^(2) ^ ^ | | | | +------------|-----+ | | | +--------+ 書式と、値の引数は、現れる順番で対応 printf の動作原理 後でちゃんと話すので、今回は我慢 !! scanf scanf : 超高機能入力関数 # printf と対応している scan with format (書式付き入力) 色々な型のデータを読み込む事ができる ( cf. s_input_int : 単機能 ) 「書式('%' + 書式指示)」を指定する事により何(基本型+文字列)が入力できる int a; scanf ( "%d", &a ); scanf は、入力した値を、(適切な型に変換して) 変数に代入する # int a; scanf ( "%d", &a ) <=> a = s_input_int() # char c; scanf ( "%c", &c ) <=> c = s_input_char() !! 変数(a) の前の 「&」は「お呪い」(後でちゃんと話す) !! 「&」を忘れると、『大問題』になる !! scanf に関しては、*あえて* 単機能的な使い方だけを紹介 !! 1. 一つの scanf では一つのデータの入力しか行わない !! 2. 書式指定文字列は、単一の書式しかかなない 書式や機能などについても printf と同様に考えてよい ## 超高機能 ## 文字列の中から値を取り出す事も ## できるのだが.. (結構難しいのでさけるのが無難 .. )
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20201002-01.c
/* * 20201002-01-QQQQ.c * * コマンドラインで指定された整数値の総和を計算する */ #include <stdio.h> /* * main */ int main ( int argc, char *argv[] ) { int sum = 0; /* 総和の値を保持する変数 */ int n = 1; /* 現在参照している引数の番号 */ while ( n < argc ) { /* 引数のある限り */ /* その引数の文字列を整数値に変換し、加える */ /* ** この部分を完成させなさい */ /* 次の引数を参照するために、参照する番号を増やす */ n = n + 1; } /* 結果を出力 */ printf ( "引数で指定された整数値並びの総和は %d です。\n", sum ); return 0; }
$ ./20201002-01-QQQQ.exe 123 456 789 引数で指定された整数値並びの総和は 1368 です。 $
Download : 20201002-02.c
/* * 20201002-02-QQQQ.c * コマンドラインでファイル名を指定して、画面に表示する */ #include <stdio.h> /* * main */ int main ( int argc, char *argv[] ) { FILE *fp; int ch; /* 入力される文字コード */ /* 引数が指定されているかどうかを判定 */ if ( argc < 1 ) { /* 引数がない */ fprintf ( stderr, "引数を指定してください\n" ); return -1; } /* 最初の引数をファイル名として open (二つ目以後は無視) */ /* ** この部分を完成させなさい */ /* ファイルが open できたかどうかを判定 */ if ( fp == NULL ) { fprintf ( stderr, "ファイル(%s)の open に失敗しました\n", argv[1] ); return -2; } /* 最初の一文字を読み込む */ /* ** この部分を完成させなさい */ while ( ch != EOF ) { /* EOF は、ファイルの終りを表す整数値 */ /* 画面に入力した文字を出力 */ putchar ( ch ); /* 次の一文字を読み込む */ ch = fgetc ( fp ); } fclose ( fp ); return 0; /* 正常終了 */ }
$ ./20201002-02-QQQQ.exe sample.txt This is sample data. 2 lines includes. $