/*
* 課題 CNAME-02
*
* CDATE FILENAME
*
* 代入文
* 整数型変数 ( a, b, c ) を三つ宣言する
* 整数型変数 a, b にそれぞれ、123, 4 を代入する
* 整数型変数 c に a と b の和を代入する
* 整数型変数 c の値を画面に出力する
*/
#include <stdio.h>
#include "s_print.h"
/*
* main
*/
int main( int argc, char *argv[] )
{
/* 整数型変数 a の宣言 */
int a;
/* 整数型変数 b の宣言 */
int b;
/* 整数型変数 c の宣言 */
int c;
/* 整数型変数 a に 123 を代入 */
a = 123;
/* 整数型変数 b に 4 を代入 */
b = 4;
/* 整数型変数 c に、変数 a と 変数 b の和を代入 */
c = a + b;
/* 整数型変数 c の値を画面に出力 */
s_print_string ( "変数 c の値は " );
s_print_int ( c );
s_print_string ( " です。\n" );
return 0;
}
#include <stdio.h>
#include "s_print.h" /* この講義でのみ使う表現 */
/*
二つの整数値の和を出力する
*/
void print_add_num ( int n, int m ) {
s_print_string ( "二つの整数値の和は " );
s_print_int ( n + m );
/* 変数 n, m に具体的な数値が割り当てられていれば */
/* 数式(文字式)「n + m」で、二つ変数が持つ値の「和」が表現できる */
s_print_string ( "です。\n" );
}
int main(void) {
print_add_num ( 3, 8 ); /* 3, 8 という実引数を与えて、関数呼び出し */
/* 実引数は、仮引数変数 n, m の値を割り当てる */
print_add_num ( 123, 456 );
return 0;
}
#include <stdio.h>
#include "s_print.h"
/*
引数で与えられた、整数値と、その次の整数値を出力
*/
void print_num_and_num_plus_one ( int num ) {
s_print_int ( num ); /* 引数で与えれた数自身 */
s_print_string ( ", " );
s_print_int ( num + 1 ); /* 引数で与えれた数の次の数 */
s_print_string ( "\n" );
}
int main(void) {
print_num_and_num_plus_one ( 123 );
print_num_and_num_plus_one ( 9876 );
return 0;
}
#include <stdio.h>
#include "s_print.h"
/*
引数で与えられた、整数値と、その次の整数値を出力
代入版
*/
void print_num_and_num_plus_one ( int num ) {
/* 変数 num には、引数で指定された値が割り当てられている */
s_print_int ( num ); /* 引数で与えれた数自身 */
/* 変数 num には、実引数の値が入っている */
s_print_string ( ", " );
num = 999; /* 変数 num に無条件に
値 999 を代入 */
/* 変数 num には、代入された 999 という値が入っている */
s_print_int ( num ); /* 引数で与えれた数の次の数 */
/* 変数 num には、最後に代入された値 999 が入っている */
s_print_string ( "\n" );
}
int main(void) {
print_num_and_num_plus_one ( 123 );
print_num_and_num_plus_one ( 9876 );
return 0;
}
#include <stdio.h>
#include "s_print.h"
/*
引数で与えられた、整数値と、その次の整数値を出力
代入版
*/
void print_num_and_num_plus_one ( int num ) {
/* 変数 num には、引数で指定された値が割り当てられている */
s_print_int ( num ); /* 引数で与えれた数自身 */
/* 変数 num には、実引数の値が入っている */
s_print_string ( ", " );
num = /* num の「引数の値」に 1 を加えたもの */
/* num の「現在の num の値」に 1 を加えたもの */
num + 1;
/* 「num = num + 1」*/
/* 「0 = 1」と思いそうだが、誤り */
/* C 言語では、「=」(等号)を「等式」に利用せず、「代入」に利用する */
/* 「x = 1」は、C 言語では x に 1 を「割り当てる(代入)」の意味で、
x と 1 が等しいという等式の意味ではない
C 言語では、「等式」は、「==」という記号で表現する
「 1 == 1 」は正しい(真となる/成立する)等式
「 1 == 0 」は誤った(偽となる/成立しない)等式
*/
/*
代入文
num = num + 1;
により、
変数 num に、「現在の変数 num の値と 1 の和」を計算した値
が代入される
=>
「変数 num の値を 1 増やす」事になる
*/
s_print_int ( num ); /* 引数で与えれた数の次の数 */
/* 引数 123 -> 124 */
/* 引数 9876 -> 9877 */
s_print_string ( "\n" );
}
int main(void) {
print_num_and_num_plus_one ( 123 );
print_num_and_num_plus_one ( 9876 );
return 0;
}
#include <stdio.h>
#include "s_print.h"
/*
引数で与えられた、整数値と、その次の整数値を出力
代入版
*/
void print_num_and_num_plus_one ( int num ) {
int mum = 0;
/* 新しい整数型の局所(local)変数 mum の宣言 */
/* 宣言したばかりの変数の値は「不定」なので
局所変数は必ず、代入して使う必要がある */
/* ここでは、初期値 0 で初期化している */
s_print_int ( num ); /* 引数で与えれた数自身 */
s_print_string ( ", " );
mum = num + 1; /*
num = num + 1;
もともとあった num の値(実引数の値)
が、失われてしまう(破壊的な振る舞い)
これがいやなら
別の変数を用意して、
その変数(mum)に代入する
mum = num + 1;
mum には num + 1 の値が代入される
# num の値は残っている
ただし、
新しい変数 mum を利用するには、
その変数の「宣言」が必要
=> 局所変数宣言
*/
s_print_int ( mum );
s_print_string ( "\n" );
s_print_string ( "念のため num を確認 num = " );
s_print_int ( mum );
s_print_string ( "\n" );
}
int main(void) {
print_num_and_num_plus_one ( 123 );
print_num_and_num_plus_one ( 9876 );
return 0;
}
前回(2020/09/18)の内容
ガイダンス
基本は、前期と同じ
ただし、前期の知識を仮定する
目的 : 「C 言語でプログラムが書けるようになる」事
簡単なプログラムは書ける
!! 原理的には、すでに、どんな目的のプログラムも書ける
三つの内容
プログラミング
プログラムとはなにか
プログラム作成するには、どうように考えればよいか
与えられた問題を簡単な問題に分割する(分割統治)
プログラム : 入力-処理-出力
再帰関数(帰納法) : N 一般を 1 と k -> k+1 の二つに分ける
=> 数学の概念は、プログラムの作成のヒント
操作方法 (ubuntu の操作)
コンパイル / 実行の仕方
C 言語 ( ソフトウェア概論のメイン )
プログラミング言語としての C 言語の説明
プログラムの表現の仕方
文字列の出力をするにはどうするか => printf
変数の代入をするにはどうするか => 代入文を使う
方針
同じ内容を 3 度
繰返しながら
少しずつ内容を深く進める
復習をしながら、思い出しながら、繰り返し
「実技」
学習のためには、繰り返し「手を動かす」
# 手と同時に頭も動かす
復習
1 周回 : hello world, 関数, 制御構造(順接,条件分岐,再帰)
原理的に可能なプログラムは一通りかける
2 周目 : 様々なデータ構造 ( char, int )
まだ、途中 : 早めに終らせて、3 周回のアプリ開発に行きたい
新規
変数宣言と代入文 (代入によって、変数の値を変更する)
代入
代入とは
概念 : 「変数」に「値」を「割り当て」る「操作」
変数 : 変化する「数」
変数の表し方(数学) : 文字で変数を表す
a + b = b + a (交換法則)
任意の二つの数 a, b に
「a に b を加える」、「b に a を加える」
の計算結果は等しい
=> 実際に計算する場合は、
変数 a, b に具体的な値が入っていないといけない
a <- 3
b <- 8
3 + 8 = 11 = 8 + 3
二次方程式
a x^2 + b x + c = 0
解は
x = (-b +- \sqrt{ b^2 - 4 a c }) / (2a)
実際に利用する場合は
a, b, c に値を具体的に与えないといけない
例 : a <- 1, b <- -2, c <- -3
x^2 - 2x - 3 = 0
x = ( -(-2) +- \sqrt{ (-2)^2 - 4 (1)(-3) } ) / (2 (1))
= ( 2 +- \sqrt{ 4 + 12 } ) / 2
= ( 2 +- 4 ) / 2
= 1 +- 2
= 3, -1
コンピュータ(C 言語)では「計算式」は、変数(文字)を含んだ「文字式」で表現可能
実際に計算をする場合 ( 変数に具体的な値を割り当てる必要がある )
関数呼び出しにおける「実引数(値の指定)」は、
関数の仮引数変数への「値の割り当て(代入)」を行う
# 数学の関数評価(関数値の計算)に対応
# f(x) = x^2 (関数定義)
# f(4) = 4^2 = 16
# f(4)
# f(x)=x^2
# f(x) -> x^2
# f(4) -> x^2 ( x := 4 )
# -> 4^2
# -> 16
代入文 ( C 言語において、変数に値を直接割り当てる表現 )
構文 : 変数名 = 式;
例: x = 1;
very_long_name_variable = 1 + 3 * 7 + 123;
意味 : 式の値を計算し、その結果を変数に代入する
変数に値を代入すると、
その変数には、その値が割り当てられてられて
それ以後は、その変数の値は、その値になる
# その変数を含む命令の振る舞いが変化する
代入「後」は、
その変数の値は、代入さ(割り当てら)れた値に「変化」する
(その変数が保持していた..) 代入「前」の値は、「失われ」る
# 変数は、値の「入れ物」を表現していると解釈できる
# 例 : 財布は、お金の入れ物
# 財布にいつでも、3 万円入っているわけじゃない
# => 飲みに 1 万円 => 残りは 2 万円
# 代入の結果
# その代入された変数を含む命令の振る舞いが(その変化する変数の値を利用するので..結果的に)変化する
# 代入によって、振る舞いが変わる
代入の「前」と「後」という「時間」の概念の把握が必要となる
# 「時間」が変化する <=> 「変数に割り当てられている値」が変化
表現 : 代入の構文
「変数名」=「式」 [例] a=1+2; (変数 a に 3 ( = 1+2 ) を代入)
「=」は、「代入」を表現する(等号[等しい]ではない!! / 等号は「==」)
局所変数宣言
概念 : 局所変数を宣言する
局所変数 : 関数の本体の先頭で宣言し、
その関数の本体内だけで利用可能な変数
# 「関数の中だけ」という「局所(限定された範囲)」のみ利用可能な変数
# => 「局所変数」
# !! 関数の外でも利用可能な変数 => 「大域変数」
関数(ブロック)内のみ(局所的)で有効(利用可能)な変数を宣言する
「仮引数変数(実は局所変数の一種)」以外にも、変数が増やせる
表現 : 局所変数の宣言
「変数の型名」「変数名」
[例] int a; (整数型の変数 a を宣言)
cf.
仮引数変数は、実引数の値で、「代入済」の変数
未代入の変数の値は「不定(プログラムミスの代表例 !!)」
変数は宣言と同時に「初期化(最初の代入)」できる(すべき) [例] int a=1;
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20200925-01.c
/*
* 20200925-01-QQQQ.c
*/
#include <stdio.h>
/*
* int quad_number ( int n )
* 奇数の和で二乗を計算する
*/
int quad_number ( int n ) {
if ( n <= 0 ) {
return 0;
} else {
/* 再帰呼出し */
/* n^2 = (n-1)^2 + (2n-1) */
/*
** この部分を完成させなさい
*/
}
}
/*
* main
*/
int main ( void ) {
/*
sum = 1 + 3 + .. + 9 = 25 = 5^2
*/
/* 整数型変数 sum の値を画面に出力 */
printf ( "1 から %d までの奇数の和は %d です。\n",
2 * 5 - 1, quad_number ( 5 ) );
return 0;
}
$ ./20200925-01-QQQQ.exe 1 から 9 までの奇数の和は 25 です。 $
Download : 20200925-02.c
/*
* 20200925-02-QQQQ.c
* 四角数の計算 ( while 構文 版 )
*/
#include <stdio.h>
/*
* main
*/
int main ( void ) {
/* 整数型変数 odd の宣言とその初期化 ( 初期値は 1 を指定 ) */
int odd = 1;
/* 整数型変数 sum の宣言とその初期化 ( 初期値は 0 を指定 ) */
int sum = 0;
/*
sum = 1 + 3 + .. + 9 = 25 = 5^2
*/
/* odd の値が 9 以下の間は繰り返す */
while ( /* q:ここ */ ) {
/* sum に odd の値を「追加」する */
/*
** この部分を完成させなさい
*/
/* odd の値を次の奇数にする */
odd = odd + 2;
}
/* 整数型変数 sum の値を画面に出力 */
printf ( "1 から %d までの奇数の和は %d です。\n",
2 * 5 - 1, sum );
return 0;
}
$ ./20200925-02-QQQQ.exe 1 から 9 までの奇数の和は 25 です。 $
Download : 20200925-03.c
/*
* 20200925-03-QQQQ.c
* ファイルの中の数値の総和
*/
#include <stdio.h>
/*
* main
*/
int main ( void ) {
FILE *fp; /* 入力するファイルへのファイルポインタ値を持つ変数 */
int num; /* 入力された一つの整数値を持つ変数 */
int sum; /* 合計値 */
/* ファイル 「num.txt」を、読込モード 「r」で開く (open) */
/*
** この部分を完成させなさい
*/
if ( fp != NULL ) { /* ファイルのオープンができた */
sum = 0; /* 総和を 0 で初期化 */
while ( fscanf ( fp, "%d", &num ) > 0 ) { /* データを読み込む */
/* データがある限り.. */
/* sum に読み込んだ値 (num) を加える */
/*
** この部分を完成させなさい
*/
}
printf ( "総和は %d です。\n", sum );
/* ファイルは必ずクローズする */
/*
** この部分を完成させなさい
*/
} else {
/* エラーメッセージを出力 */
fprintf ( stderr, "ファイルがオープンできません\n" );
return -1; /* エラー終了 */
}
return 0;
}
$ ./20200925-03-QQQQ.exe 総和は 258 です。 $