• 検索結果がありません。

四則演算

ドキュメント内 新潟大学学術リポジトリ (ページ 42-49)

5.2. 四則演算 37

10 product = a*b;

11 quotient = a/b;

12 remainder= a%b;

13 printf("\nInput data: %d, %d\n\n"

14 "Sum: %d\n"

15 "Difference: %d\n"

16 "Product: %d\n"

17 "Quotient: %d\n"

18 "Remainder: %d\n",

19 a, b, sum, diff, product, quotient, remainder);

20 return 0;

21 }

[motoki@x205a]$ gcc -o arith-op arithmetic-operations-over-int.c Enter ... (実行ファイルの名前を指定してコンパイル) [motoki@x205a]$ ./arith-op Enter... (実行) 11 3 Enter... (データの入力) Input data: 11, 3

Sum: 14

Difference: 8 Product: 33 Quotient: 3 Remainder: 2 [motoki@x205a]$

ここで、

• プログラムの1〜2行目 は注釈。

• プログラムの3行目 は、/usr/include/stdio.h というファイルの中身をこの場所に 挿入してコンパイル作業を行うことを指示する。

• プログラムの4〜21行目 はmain関数の定義。

• プログラムの6行目 は、整数データを格納するための領域を7つ確保し、それぞれa, b, sum, diff, product, quotient, remainderと名付けることをコンパイラに知らせ る宣言文である。「int」と指定することにより、確保した領域が 整数データの内部 表現形式(3.4節) に従ってデータを保持する様になる。

'

&

$

% 補足:

intの様に、内部表現形式に起因するデータの種類を一般にデータ型(data type) と呼ぶ。C言語においては、intは整数を表すための最も標準的な内部表現形式 に対応したデータ型である。intの他には実数データを保持するためのfloat

doubleといった(基本)データ型も用意され、また、(基本)データ型を複数組み

合わせて新しいデータ型を定義することもできる。=11節を参照。

• プログラミング(programming;i.e.プログラム作成の作業)の際には、a,b, sum, ... の 様に、プログラムの中でデータを記憶するために確保され使われる記憶領域のことを

一般に変数(variable)と呼ぶ。

'

&

$

% 変数の名前の付け方:

C言語では、変数に付ける名前として、

英字(または下線)で始まり、それに英数字や下線が続く文字の並び

を使うことが出来る。(大文字と小文字は区別する。)こういった制約の下で、使 い方/役割に応じた適切な名前を付けることが大切である。=p.44を参照。

補足:

「変数」という用語は数学にも出て来る。プログラミングの場合も数学の場合も 元々の英語の用語は“variable”で、ともに

使う時点によって 表す対象/内容が変わり得るもの という意味である。

確かに、数学で 「関数f(x) =x2+ 1」 と言った場合の変数xは実数上で色々 と変わる値を表すものだし、プログラムにおける変数 aはプログラムの実行状 況に応じて色々な値を保持するもの(記憶領域)になっている。

• プログラムの7行目 は標準ライブラリの中に用意されている書式付き入力の関数scanf を呼び出している。 この呼出しの際にscanf関数に引き渡されるデータ(引数,ひきす

う, またはパラメータと言う) を指定しているのが、“scanf” に続く丸括弧 ( ) で囲 まれた部分である。各々の引数はコンマで区切られているので、7行目には全部で3 つの引数が指定されていることになる。このうち、第1引数は入力の書式を表す文字 列、2番目以降の引数は入力データを格納する領域の番地(address)を表している。こ こで指定された入力書式の中の%d は、読み込んだデータ(数字の列)を 整数 の内部 表現形式に変換して、然るべき記憶領域に格納することを指示している。 また、例 えば第2引数の &a は変数a (が置かれる主記憶上)の番地を表す。

'

&

$

% 補足:

単にaと書いたのでは変数aの保持する値がscanf関数に送られてしまい、

scanf側では読み込んだデータの格納場所が分からない。

• プログラムの8行目 は sum←− a + b すなわち

(変数a に保持されている値) + (変数 b に保持されている値) を計算して、その結果を変数 sumに格納する

という動作を表しています。 同様に、プログラムの9〜12行目 は各々 diff←− a −b,

product←− a × b,

quotient←− a ÷ b, . . . ( 小数部は捨てられ、結果は整数になる ) remainder←− (aの値)を(bの値)で割った時の余り,

という動作を表しています。

• プログラムの13〜19行目 は、標準ライブラリの中に用意されている書式付き出力の

関数 printf を呼び出している。13〜18行目の、2重引用符で囲まれた部分が出力書

式になっていて、この指示に従った様式で関数printfの第2引数以下(19行目)の部分 で指定された式の値が順に出力される。 [13〜18行目は途中にコンマが無いので、

1つの引数として扱われる。2重引用符で囲まれた文字列が6つ並んでいるが、この 部分はこれらの文字列を並べた1つの文字列と同等である。] これにより、結局次 のような出力がなされる。但し、ここでは空白は と明示している。

5.2. 四則演算 39

空行

Input data: 2引数で指定された式aの値, 3引数で指定された式bの値 空行

Sum: 4引数で指定された式sumの値

Difference: 5引数で指定された式diffの値

Product: 6引数で指定された式productの値

Quotient: 7引数で指定された式quotientの値

Remainder: 8引数で指定された式remainderの値

ここで注目すべき点は次の通りである。

3 出力書式中に現れる %d という部分が第2引数以降の式と順にペアにされ、式の

値(を我々が見える文字列で表したもの)に置き換えられる。

3 出力書式中の \n は改行を指示する。

3 出力書式中の%d は別途指定された式の値が固定小数点数型(整数型)の内部表現 形式に従っていると仮定して、これを10進の文字列に変換して、この%dの場所 に出力することを指示する。

3 出力書式中の \n, %d 以外の文字列はそのまま出力される。

• gccコマンドの次に -o ファイル名 という形のオプションを入れると実行ファイル の名前を指定することができる。 上のコンパイル例の場合は、これによってarith-op という名前の実行ファイルが作られている。

代入文: “sum=a+b;”の様に、プログラムの中で

式の計算をして その結果を指定された変数に格納する動作を表す部分

を一般に代入文(assignment statement) と呼ぶ。特にC言語においては、変数名や 123 といった数を表す文字列に 8〜12行目の演算子や丸括弧を組み合わせて色々な を構成 し、

変数名 = ;

変数名 += ; . . . .( 変数名 = 変数名 + ; と同等 ) 変数名 -= ; . . . .( 変数名 = 変数名 - ; と同等 ) 変数名 *= ; . . . .( 変数名 = 変数名 * ; と同等 ) 変数名 /= ; . . . .( 変数名 = 変数名 / ; と同等 ) 変数名 %= ; . . . .( 変数名 = 変数名 % ; と同等 )

...

という形の代入文を書くことができる。

例 5.4 (代入文) int型変数sum, x に関して、次の2つの代入文は同じ計算を行う。

sum = sum + x;

sum += x;

算術式の計算: (コンピュータによる)代入文の実行においては、等号の右側の算術式の 計算は通常の数学と同じ順序で1つずつ行われる。 すなわち、丸括弧によって計算の順 序が指定されていない場合、

• 乗除算, 剰余演算(*, /, %)を加減算(+, -)より先に行う。

• 乗除算, 剰余演算(*, /, %)の間では、左にあるものを優先する。

• 加減算(+, -)の間では、左にあるものを優先する。

当然、途中で行われる各々の演算の結果はコンピュータの中に(一時的に)保持されなけ ればならず、演算結果を保持する内部表現形式も決まっているはずである。 そのために、

算術式を構成する各々の(部分)算術式に対して、そのデータ型が定められている。 特に int型データ同士の演算の場合は、演算結果はint型と定められている。

例 5.5 (算術式における演算順序の指定) int型変数 h, m, s, timeに関して、次の4つ の代入文は同等の計算結果をもたらす。

time = h*60*60 + m*60 + s;

time = (((h*60)*60) + (m*60)) + s;

time = (h*60 + m)*60 + s;

time = h*3600 + m*60 + s;

例 5.6 (式の計算に関する注意) int型同士の除算においては商の小数部は捨てられる。そ

のため、数学的に等しい式であっても、C言語の算術式としては異なる値を持つことがあ る。例えば、数学的には 1/2∗a=a∗1/2 であるが、大抵の場合2つの代入文 x=1/2*a;

と x=a*1/2; は異なる実行結果をもたらす。 実際、x=1/2*888; を実行すると変数 x に は値 0が格納され、x=888*1/2; を実行すると変数 x には444 という値が格納される。

例題 5.7 (直方体の体積) 3つの整数データ x, y, a を読み込み、それらを使って 縦,横が各々 xcm, ycm の厚紙の四隅をacm 四方だけ切り取ってできる直方体 の体積を計算して出力するCプログラムを作成せよ。

a

x

y

この処理のために、 厚紙の縦,横,切り取る正方形 の一辺の長さを記憶する領域を用意し各々 x, y, a という名前を付けることにする。すると、縦がx-2*a cm, 横が y-2*a cm, 高さが a cm の直方体が出来る から、求める体積は(x-2*a)*(y-2*a)*a と計算でき る。そこで、データ入力を促す文字列も出すことに

し、またprintf 関数を使って算術式の計算結果を変

数に格納せずにそのまま出力することにすれば、コン ピュータが行うべき処理は右図の様に書き表すことが できる。

開始

入力 (プロンプト付き) x, y, a

x, y, a は正整数で a<x, a<y と仮定

終了

出力 "==> 直方体の体積 = ", (x-2*a)*(y-2*a)*a

5.2. 四則演算 41

この処理を行うCプログラムと、これをコンパイル/実行している様子は次に示す通りで

ある。 (下線部はキーボードからの入力を表す。)

[motoki@x205a]$ nl rectangular-parallelepiped.c

1 /* 3つの整数データ x, y, a を読み込み、それらを使って */

2 /* 縦,横が各々 x,y の厚紙の四隅を a 四方だけ */

3 /* 切り取ってできる直方体 */

4 /* の体積を計算して出力するCプログラム */

5 #include <stdio.h>

6 int main(void) 7 {

8 int x, y, a;

9 printf("厚紙の縦 = ? ");

10 scanf("%d", &x);

11 printf("厚紙の横 = ? ");

12 scanf("%d", &y);

13 printf("切り取る正方形の一辺 = ? ");

14 scanf("%d", &a);

15 printf("\n==> 直方体の体積 = %d 立方cm\n", 16 (x-2*a)*(y-2*a)*a);

17 return 0;

18 }

[motoki@x205a]$ gcc rectangular-parallelepiped.c [motoki@x205a]$ ./a.out

厚紙の縦 = ? 38 厚紙の横 = ? 57

切り取る正方形の一辺 = ? 8

==> 直方体の体積 = 7216 立方cm [motoki@x205a]$

ここで、

• プログラムの1〜3行目 は注釈。

• プログラムの8行目 は、int型データを格納するための領域を3つ確保し、それぞれ x, y, a と名付けることをコンパイラに知らせる宣言文である。

• プログラムの9行目,11行目,13行目 はデータの入力を促す文字列(プロンプトと呼ぶ) を出力している部分である。続く10行目,12行目,14行目 で、各々のプロンプトに対 するデータ入力が行われる。

• プログラムの15〜16行目 は、書式付き出力の関数 printfを呼び出している。これに より、結局次のような出力がなされる。

空行

==> 直方体の体積 = 2引数で指定された式 (x-2*a)*(y-2*a)*a の値 立方cm ここで注目すべき点は次の通りである。

3 C言語の printf 関数においては、出力データを算術式で指定することができる。

'

&

$

% 補足:一般に、プログラムの中でコンピュータの基本動作に相当する部分を文

(state-ment)と呼ぶ。特にC言語においては、セミコロン(;) は文の終わりを表す記

号である。

C言語においては、等号=+ *と同じ様に演算子(operator)に分類され、

代入演算子と呼ばれる。 そして、変数= というもの自身が値をもつ式とし て扱われる。 [変数に値が格納されるのは単なる副作用と考える。]

□演習 5.8 (整数の商) 9桁以下の2つの正整数 m, n を入力して、

m

nの小数部を切捨てて得られる整数値 を出力するプログラムを作成せよ。

□演習 5.9 (四捨五入) 9桁以下の2つの正整数 m, n を入力して、

m

nの小数部を四捨五入して得られる整数値 を出力するプログラムを作成せよ。'

&

$

% Hint:

このプログラムは、例えば m= 7, n= 3なら2 を、m= 8, n= 3なら3 を出 力することになる。 そのために、実際にはプログラム内で

m n +1

2

=

2m+n 2n

=

m+n/2 n

の計算をint型算術式で表せばよい。 ここで、xxを越えない最大整数を 表す。

float型だと、有効桁が少ないために、入力値が大きい時に正確な数値が出力さ

れないことがある。

□演習 5.10 (時間→秒) 3つの非負整数 h, m, s を入力して、h時間m分s秒に相当す る時間の長さを秒単位に変換して出力するCプログラムを作成せよ。

ドキュメント内 新潟大学学術リポジトリ (ページ 42-49)