/*
* 課題 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. $