情報学部 菅沼ホーム 全体目次 演習解答例 付録 索引

第Ⅱ部

第3章 簡単なプログラム

  1. 3.1 プログラムの書き方
    1. 3.1.1 基本原則
    2. 3.1.2 わかりやすいプログラム
  2. 3.2 データ型
    1. 3.2.1 定数
    2. 3.2.2 変数
    3. 3.2.3 列挙型変数
    4. 3.2.4 typedef 宣言
  3. 3.3 算術演算子と代入演算子
    1. 3.3.1 算術演算子
    2. 3.3.2 代入演算子
    3. 3.3.3 インクリメント,デクリメント演算子
    4. 3.3.4 型変換( cast 演算子)
  4. 3.4 簡単なプログラム
    1. (プログラム例 3.1 ) 2 つのデータの和と差
    2. (プログラム例 3.2 ) 2 つのデータの和と差(cout,cin)(C++)
  5. 3.5 その他
    1. 3.5.1 キーワード
    2. 3.5.2 アスキーコード
    3. 3.5.3 エスケープシーケンス
  6. 演習問題3

3.1 プログラムの書き方

3.1.1 基本原則

  C/C++ は,フリーフォーマットで書くことができる言語です.つまり,日本語などのように,一つの文を任意の行・列から書き始めることが可能ですし,どこで終わっても構いません.また,日本語の場合,一つの文章が「。」で終わるように,C/C++ においてはセミコロン(;)で一つの文章が終了します.

  文章内及び文書間には,単語を分割するような位置でなければ,適当な位置に,また,適当な数だけ区切り記号(半角スペース,タブ,復改,コメント)を入れても構いません.

  コメント(説明,注釈comment)は,/* で始まり */ で終わります.コメントを複数行にわたって書くこともできますが,入れ子(ネスト)にすることは許されません.また,
// から行末まで		
というコメントの書き方も許されます.例えば,
x = 10.0;   // 変数 x に 10.0 を代入		
のように書く方法です.ただし,この方法の場合,複数行に亘ったコメントを書くことはできません(各行毎に「 // 」を付加しなければならない)./* と */ を使用した方法で書けば
x = 10.0;   /* 変数 x に 10.0 を代入 */		
となります.

3.1.2 わかりやすいプログラム

  プログラムも一種の文章です.従って,よほど特殊な事情がない限り,読みやすく,理解しやすいことが,プログラムにとって最も重要な課題となります.もちろん,誤りさえなければ,読みやすい,読みにくいに関わらず,プログラムは正しく実行されます.しかし,プログラムを実行するのはコンピュータであっても,プログラムを書いたり,誤りを修正したりするのは人間です.読みやすいプログラムを書くことにより,その内容を他人に説明することが容易になると共に,まず,自分自身が誤りを犯しにくくなります.

  次に示すのは二次方程式を解くための C/C++ のプログラムです.ただし,各行の最初の番号は,説明のために付加した行番号です.プログラムの内容とは関係ありません(以下のプログラムにおいても同様).
01	#include <stdio.h>
02	#include <math.h>
03	int main(){double a,b,c,d,x,x1,x2;
04	printf("係数a,b,及び,cは? ");scanf("%lf %lf %lf",&a,&b,&c);
05	if(fabs(a) <= 1.0e-10){
06	if(fabs(b) <= 1.0e-10)printf("解を求めることができません!\n");
07	else{x=-c/b;printf("x=%f\n",x);}}
08	else{d=b*b-4.0*a*c;
09	if(d >= 0.0){d=sqrt(d);x1=0.5*(-b-d)/a;x2=0.5*(-b+d)/a;
10	printf("x=%f %f\n",x1,x2);}
11	else{d=sqrt(-d);x1=-0.5*b/a;x2=0.5*d/a;
12	printf("x=%f ± i%f\n",x1,x2);}}return 0;}
		
  上のプログラムを見て読みやすいと感じるでしょうか.もちろん,プログラム言語に関する説明がまだですので,内容自身を的確に把握することは困難かと思います.しかし,同じプログラムを下のように書いたらどうでしょうか.内容自身についてもある程度想像が付くのではないでしょうか.

01	/*********************************/
02	/* 二次方程式を解く              */
03	/*     a * x * x + b * x + c = 0 */
04	/*          coded by Y.Suganuma  */
05	/*********************************/
06	#include <stdio.h>
07	#include <math.h>
08	
09	int main()
10	{
11		double a, b, c, d, x, x1, x2;
12	/*
13	           係数の読み込み
14	*/
15		printf("係数a,b,及び,cは? ");
16		scanf("%lf %lf %lf",&a,&b,&c);
17	/*
18	          一次方程式
19	*/
20		if (fabs(a) <= 1.0e-10) {
21			if (fabs(b) <= 1.0e-10)
22				printf("   解を求めることができません!\n");
23			else {
24				x = -c / b;
25				printf("   x=%f\n",x);
26			}
27		}
28	/*
29	          二次方程式
30	*/
31		else {
32	
33			d = b * b - 4.0 * a * c;
34	               // 2実根
35			if (d >= 0.0) {
36				d  = sqrt(d);
37				x1 = 0.5 * (-b - d) / a;
38				x2 = 0.5 * (-b + d) / a;
39				printf("   x=%f %f\n",x1,x2);
40			}
41	               // 虚数
42			else {
43				d  = sqrt(-d);
44				x1 = -0.5 * b / a;
45				x2 = 0.5 * d / a;
46				printf("   x=%f ± i%f\n",x1,x2);
47			}
48		}
49
50		return 0;
51	}
		

  プログラムをどのように書けば読みやすいかということに対する明確な定義があるわけではありません.しかし,経験的に,以下に示すような規則を守って書くと良いと思います(ただし,以下に示す 1 番目及び 2 番目のルールは必ず守ること).もちろん,個人的な好みの問題もありますので,自分自身でも適当に工夫してみて下さい.
  1. 機能ブロック毎に字下げ(上のプログラムでは,tab を使用して字下げを行っている)を行う.字下げを行うことにより,その機能ブロックの範囲が一目でわかるようになる.例えば,11~50 行目は,10 行目及び 51 行目に対して,字下げしてある(プログラムの内容であることを示している).また,36~39 行目は,35 行目及び 40 行目に対して字下げしてあるので,条件 「 d >= 0 」 が満たされたときの処理であることが一目でわかる.

  2. プログラム全体,主要な変数・引数の説明( 1~5 行目)や,プログラムの各部分に対する説明( 12~14 行目等)を必ず入れる.

  3. 一つの行に複数の文を書かない(場合によっては,複数の文を書いた方が見やすい場合もある).

  4. 読み易さを考えて適当にスペースを入れる.特に,演算子の前後には必ずスペースを入れ,また,代入文が続いたときは等号を揃える( 36~38 行目等).ただし,等号を揃えるとかえって見にくくなるような場合は,あえて揃える必要は無い.

  5. 一つのプログラムは,せいぜい,50~100 行程度以内にする.

  6. 記述しやすい,プログラムが短くなる,などといった安易な理由で,他の言語を知っている人さえ理解しにくい,または,プログラムの他の部分を参照しないと理解できないような表現を使用しない.

3.2 データ型

  数式と同じように,C/C++ においても,定数や変数を使用できます.その意味するところは,数学の場合とかなり似ています.しかし,直接対応するものが数学にはない「データ型」という概念が存在します.

  プログラムの中で使用した変数variable )や定数constant )は,必ず,主記憶上のどこかに記憶されます.また,変数に記憶されている値や定数が整数なのか,浮動小数点数(実数)なのか,文字なのか,さらに,記憶するのに何バイト必要なのか等によって,記憶する領域の大きさや表現方法が異なります.これらのことを規定するのがデータ型です.

3.2.1 定数

  定数には,整数定数浮動小数点定数文字定数,および,文字列定数の 4 種類があります( C++ の場合は,truefalse からなる論理型定数が加わります).定数の場合,そのデータ型は,定数の記述方法によって一意的に決まります.

  整数定数は,以下のように,10 進数,16 進数,8 進数,または,2 進数で記述します.

  例えば,1234 のように書けば,整数定数とみなされ,2 バイトまたは 4 バイトの領域が確保され(コンパイラによって異なる),基本的に,1.2.3.1 節で述べた整数の表現方法に従って記憶されます( int 型定数).int 型が 2 バイトで定義されており,かつ,値がその領域に入りきらないようなときは,例えば,123456789L のように,後ろに「l(エル)」または「L」(接尾子)を付加する必要があります( long 型定数).int 型が 4 バイトで定義されているような場合は,long 型と int 型は同じものになり,このようなことを考慮する必要はありません.ただし,8 バイトで定義される long long 型定数の場合は,123451234512345LL のように,「ll」または「LL」を付加する必要があります.

  1234.0 のように,小数点を使用して数値を記述すると,それは浮動小数点型定数となり,8 バイトの領域が確保され,基本的に,1.2.3.2 節で述べた浮動小数点数の表現方法に従って記憶されます( double 型定数long double 型定数の場合は,1234.0L のように,l,または,L を付加する必要がある).もし,多くの有効桁数を必要とせず,かつ,メモリを節約したい場合には,1234.0F のように,接尾子「f」または「F」を付けることにより,4 バイトの浮動小数点数で表現することも可能です( float 型定数).また,1234.0 を,1.234e+3 ( 1.234×10+3 の意味)のようにも表現可能です.

  文字定数は 'a'( a は 1 バイトの文字),また,文字列定数は "abc" のように記述します.ここで注意すべきことは,'a' と "a" が同じでは無いという点です.前者は文字 a が入る 1 バイトの領域が確保されますが,後者では,2 バイトの領域が確保され,文字 a と共に,文字列の終わりであることを示す '\0'(ヌル文字)が記憶されます.このように,文字列定数の場合,与えられた文字列の最後にヌル文字が付加され,実際の文字数より 1 文字文だけ多い領域が確保されます.従って,'漢'は文字定数として正しい表現のように見えますが,全角文字は 2 バイトで表現されますので,誤りとなります.全角文字は,たとえそれが 1 文字であっても,"漢"のように,文字列定数として記述する必要があります.なお,文字列定数を,
"abcd" "efgh"		
のように半角スペースや改行で区切って並べた場合,それらは一つの文字列(この場合は,"abcdefgh")とみなされます.

3.2.2 変数

  変数は,数値や文字を記憶するメモリ内の特定の領域に着けられた名前です.定数とは異なり,あらかじめそこに記憶されるデータが常に決まっているわけではありません.しかし,データの型により,必要とする領域の大きさや表現方法が異なりますので,ある変数が示す領域に任意のデータを記憶するわけにはいきません.前もって,その領域に記憶可能なデータのtype )を指定してやる必要があります.これを,変数の型宣言と言います.

  基本的に,C/C++ で使用するすべての変数に対しては,後に示すような型宣言文を使用して,変数が使用される前に,その変数の型を定義してやる必要があります.型宣言された変数の有効範囲(その変数を参照可能な範囲)は,型宣言をされた位置からブロック( { と } で囲まれた部分)の終わりまでです.例えば,以下に示すプログラムにおいて,04 行目において型宣言された変数 k と x の有効範囲は 04 行目~ 15 行目,また,10 行目において型宣言された変数 y の有効範囲は 10 行目~ 12 行目になります.ただし,04 行目で型宣言された変数 x と同じ名前の変数が 10 行目においても型宣言されています(この方法は,使用しない方が良い).そのため,10 行目~ 12 行目においては,10 行目で型宣言された変数 x が有効になります.また,変数 k を 07 行目~ 12 行目内だけで使用する場合は,変数 k の型宣言を 04 行目では行わず,07 行目を,
for (int k = 0; k < 2; k++) {		
のように記述することも可能です( C++ の場合,for 文に関しては後述).
01	#include 
02	int main()
03	{
04		int k, x = 10;
05		x++;
06		printf("x %d\n", x);
07		for (k = 0; k < 2; k++) {
08			x++;
09			printf("   x %d\n", x);
10			int x = 20, y = 100;
11			printf("   x,y %d %d\n", x, y);
12		}
13		printf("x %d\n", x);
14		return 0;
15	}
		
  型宣言文の形式は以下に示すとおりです.
データ型 変数名1[= 初期値], 変数名2[= 初期値], ・・・;		
  データ型とは,char,int 等であり,例えば,変数 x の型を宣言するためには,基本的に,以下のいずれかの型を選択します.
データ型            バイト数と値の範囲
void                *  *
char                1  -128 ~ 127(文字型,1 バイトの整数型)
unsigned char       1  0 ~ 255(文字型,1 バイトの符号無し整数型)
short               2  -32,768 ~ 32,767( 2 バイトの整数型)
unsigned short      2  0 ~ 65,535( 2 バイトの符号無し整数型)
int                 *  システム依存(整数型)
unsigned int        *  システム依存(符号無し整数型)
long                4  -2,147,483,648 ~ 2,147,483,647( 4 バイトの整数型)
unsigned long       4  0 ~ 4,294,967,295( 4 バイトの符号無し整数型)
long long           8  -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807( 8 バイトの整数型)
unsigned long long  8  0 ~ 18,446,744,073,709,551,615( 8 バイトの符号無し整数型)
float               4  3.4E±38(浮動小数点型,有効桁は約 7 桁)
double              8  1.7E±308(浮動小数点型,有効桁は約 15 桁)
long double         *  拡張精度,システム依存(浮動小数点型)
bool(C++)             1  true( 0 以外) or false( 0 )(論理型),数値の 0 は false に,その他は true に変換される
auto(C++11)            *  代入された値によって型を推論する		

-----------------------(C++)データ型-----------------------

  以下に示すプログラムにおいては,C++ の出力方法が使用されています.後に説明しますように,cout は,<< と << で挟まれたデータが出力されます.その際,文字列はそのまま,それ以外の変数や式は,適当に変換されて出力されます.なお,endl は,改行を表しています.

  C/C++ においては,0 は偽( false ),それ以外は真( true )になります.従って,08 ~12 行目とそれに対応する出力から分かるように,x1,y1,z1 の値や (x1 + z1) の値はそのまま出力され,比較演算の結果は真か偽によって 1 か 0 が出力されます.これらの結果は,C における出力方法を使用しても全く同じです.

  14 行目以降は,C++ における処理です.各変数を int で宣言した場合と bool で宣言した場合を比較しています.boolalpha を出力した以降は,真や偽を 1 と 0 ではなく,true と false で表します.なお,元の状態に戻したいときは,noboolalpha を出力します.14 ~ 18 行目は,C の場合と同じですが,それ以降は,型宣言の方法( int と bool )や boolalpha を出力したか否かによって異なってきます.
01	#include <iostream>
02	
03	using namespace std;
04	
05	int main()
06	{
07				// C
08		cout << "C int 宣言\n";
09		int x1 = 5, y1 = 1, z1 = 0;
10		cout << "  x1 " << x1 << " y1 " << y1 << " z1 " << z1 << endl;
11		cout << "  (x1 > y1)? " << (x1 > y1) << " (x1 < y1)? " << (x1 < y1) << endl;
12		cout << "  (x1 + z1) " << (x1 + z1) << endl;
13				// C++
14		cout << "C++ int 宣言" << endl;
15		int x2 = 5, y2 = 1, z2 = 0;
16		cout << "  x2 " << x2 << " y2 " << y2 << " z2 " << z2 << endl;
17		cout << "  (x2 > y2)? " << (x2 > y2) << " (x2 < y2)? " << (x2 < y2) << endl;
18		cout << "  (x2 + z2) " << (x2 + z2) << endl;
19	
20		cout << "C++ bool 宣言\n";
21		bool x3 = 5, y3 = 1, z3 = 0;
22		cout << "  x3 " << x3 << " y3 " << y3 << " z3 " << z3 << endl;
23		cout << "  (x3 > y3)? " << (x3 > y3) << " (x3 < y3)? " << (x3 < y3) << endl;
24		cout << "  (x3 + z3) " << (x3 + z3) << endl;
25	
26		cout << "C++ int 宣言 (boolalpha)" << boolalpha << endl;
27		int x4 = 5, y4 = 1, z4 = 0;
28		cout << "  x4 " << x4 << " y4 " << y4 << " z4 " << z4 << endl;
29		cout << "  (x4 > y4)? " << (x4 > y4) << " (x4 < y4)? " << (x4 < y4) << endl;
30		cout << "  (x4 + z4) " << (x4 + z4) << endl;
31	
32		cout << "C++ bool 宣言 (boolalpha)\n";
33		bool x5 = 5, y5 = 1, z5 = 0;
34		cout << "  x5 " << x5 << " y5 " << y5 << " z5 " << z5 << endl;
35		cout << "  (x5 > y5)? " << (x5 > y5) << " (x5 < y5)? " << (x5 < y5) << endl;
36		cout << "  (x5 + z5) " << (x5 + z5) << endl;
37	
38		return 0;
39	}
		
(出力)
C int 宣言
  x1 5 y1 1 z1 0
  (x1 > y1)? 1 (x1 < y1)? 0
  (x1 + z1) 5
C++ int 宣言 (noboolalpha)
  x2 5 y2 1 z2 0
  (x2 > y2)? 1 (x2 < y2)? 0
  (x2 + z2) 5
C++ bool 宣言 (noboolalpha)
  x3 1 y3 1 z3 0
  (x3 > y3)? 0 (x3 < y3)? 0
  (x3 + z3) 1
C++ int 宣言 (boolalpha)
  x4 5 y4 1 z4 0
  (x4 > y4)? true (x4 < y4)? false
  (x4 + z4) 5
C++ bool 宣言 (boolalpha)
  x5 true y5 true z5 false
  (x5 > y5)? false (x5 < y5)? false
  (x5 + z5) 1
		
  auto 宣言(C++11)を使用すると,以下に示すプログラムのように,変数等の型がそこに代入された値によって推論,決定されます.
#include 

class Test {
	public:
		int x, y;
		Test(int x1, int y1) {
			x = x1;
			y = y1;
		}
};

int add(int x, int y)
{
	return x + y;
}

int main()
{
			// int
	auto x = 10, y = 20;
	printf("%d + %d = %d\n", x, y, add(x, y));
			// クラス Test のオブジェクト
	auto a = Test(1, 2);
	printf("a.x %d a.y %d\n", a.x, a.y);
			// 関数の型
	auto fp = add;
	auto z  = 30;
	printf("%d + %d = %d\n", x, z, (*fp)(x, z));

	return 0;
}
		
  このプログラムを実行すると,以下に示すような結果が得られます.
10 + 20 = 30
a.x 1 a.y 2
10 + 30 = 40		
  また,C++ には,オペランドで指定した式の型を取得するための decltype(C++11) が存在します(あまり,使用すべき機能では無いと思います).decltype は,以下に示すような形で使用します.なお,int& の & は,参照を表す演算子であり,変数 c が 変数 a の別名であることを意味します.従って,c ( a )の値を変更すれば,a ( c )の値も変化します.
int a = 10;
decltype(a) b = (int)31.5;   // int b = (int)31.5;
decltype((a)) c = a;   // int& c = a;
decltype(1+2.3) x = 3.5;   // double x = 3.5;
cout << "a " << a << " b " << b << endl;
c = 20;
cout << "a " << a << " c " << c << endl;
cout << "x " << x << endl;		
(出力)
a 10 b 31
a 20 c 20
x 3.5		

--------------------(C++)データ型終わり--------------------

  変数が定義されただけでは,その変数が示す領域にどのようなデータが入っているかは未定です( auto を除く).もし,最初,その変数の領域に何らかの値を設定しておきたい場合は,初期値の項を記述してやることによって可能です(初期化初期設定).例えば,double 型変数 x の初期値を 10.5 としたい場合は,以下のように記述します(この段階で,変数 y の値は未定).なお,2 行目に示すように,const を付加して定義すると,以後,その変数の値を変更できなくなります.
double x = 10.5, y;
const int z = 20;		
  変数名としては,英字と数字を利用でき,一般的には小文字を使用しますが,大文字を使用することもあります.大文字と小文字は厳密に区別され,変数 a と変数 A は,異なる変数とみなされます.また,変数名の最初の文字は必ず英字でなくてはなりませんが,英字の代わりに下線 「 _ 」 を使用することも可能です.下線 「 _ 」 は,英字とみなされ,例えば,english_test のように,長い変数名を読みやすくするために使用されます.変数名の長さについては,特別な制限はありませんが,31 文字を超えた部分については一義性が保証されません.

  基本的には,変数名としてどのような名前を付けても構いませんが,C/C++ 言語の中で特別な意味を持っている if,else,int,float 等のキーワード(keyword,予約語)は予約済みであり,変数名として使用してはいけません.

  以上述べたことのまとめとして,型宣言文の例を挙げておきます.
int abc, _bef;   // 正.複数の変数をカンマで区切って並べることが可能
double abc, _bef = 3.5;   // 正.変数 _bef に対しては初期設定を行っている
int a, A;   // 正.変数 a と A は異なる
char a = 'A';   // 正.変数 a を A という文字(アスキーコードで 65 )で初期化
char a = 65;   // 正.変数 a を 65 で初期化(上と同等,char は,1 バイトの整数とみなすことができる)
int a, abc, a;   // .同じ変数を 2 度定義してはいけない
int if;   // .キーワードは変数名として使用できない
int 10a;   // .変数名の最初は,英字または下線
int a+10;   // .変数名に使用できるのは,英数字と下線だけ
int a = 3.5;   // .int 型の変数の初期値として不適当
char a = "ABC", b = "漢";   // いずれも.単純変数に文字列を記憶することはできない		

3.2.3 列挙型変数

  変数・定数の特別な型として,列挙型変数・列挙定数があります.例えば,変数 color の値が 0 のときは赤,1 のときは青等を表したいとします.しかし,このような数字での記述だと各数字が何色を表現しているのかが分かり難くなります.そこで,変数 color を列挙型変数として,
enum coltype {red, blue, black, white} color;		
のように宣言しておくと( red,brue 等を列挙定数と呼びます),
color = blue;           /* 変数 color に青を代入 */
if (color == red)       /* もし,色が赤ならば */		
のような表現が可能になります.列挙定数は int 値を持ち,その値は,順に,0,1,2,・・・となります.ただし,'=' 演算子を使用して,その値を変更することができます.例えば,
enum coltype {red, blue, black=5, white} color;		
とすると,各列挙定数の値は,
red : 0,  blue : 1,  black : 5,  white : 6		
となります.列挙型の宣言方法の一般形式は以下のようになります.
enum [列挙型名] [{列挙定数リスト}] [変数リスト];		
また,型宣言と変数の宣言を以下のように,別々に書くこともできます.
enum coltype {red, blue, black, white};
enum coltype color;		

3.2.4 typedef 宣言

  次の方法により,既存のデータ型に別の名前を与え,新しいデータ型の名前を作成することが可能です.
typedef 既存のデータ型 同義語名		
例えば,
typedef int word;
using word = int;   // C++ の場合はこの方法でも可		
と宣言することにより,変数 x を int で宣言するのに,
word x;		
と書くことができます.ただし,この例に挙げたような場合に安易に typedef を使用すべきではありません.書いた本人にとっては分かりやすいでしょうが,他の人にとってはその定義をされた場所を探さねばならず,その人にストレスを感じさせ,「読みやすく,理解しやすい」プログラムという趣旨に反します.しかし,絶対に typedef を使用すべきではないという意味ではありません.例えば,
vector<pair<double,double>>		
のような長い名前の型(厳密には型ではありせんが,この段階ではそのように理解してください)をそのまま記述すると,一つの文が長くなりすぎ,複数行に亘るなど,読みにくくなってしまうような場合があります.このような場合には,例えば次に示す例のように,typedef を使用すべきかもしれません.
typedef vector<pair<double,double>> vp;
using vp = vector<pair<double,double>>;   // C++ の場合はこの方法でも可		

3.3 算術演算子と代入演算子

  C/C++ において使用できる演算子operator )には,多くのものが存在しますが,この節では,その代表的なものについて説明します.

3.3.1 算術演算子

  プログラムを構成する最も基本的な処理は,定数と変数を使用し何らかの計算を行うことです.その際使用される算術演算子としては,以下のようなものがあります.
+ : 加算
- : 減算
* : 乗算
/ : 除算(整数どうしの除算は,結果の小数点以下を切り捨て)
% : 余り(整数演算に対してだけ使用可能)		
数学の場合と同様に,これらの算術演算子と括弧を使用して,様々な計算を行うことができます.

  記述された計算式は,基本的に,左から順に計算されていきます.しかし,「+」や「-」は,「*」や「/」や「%」より優先度が低いため,「*」等より後に計算されます.しかし,括弧があれば,その中が最も優先的に計算される点は,数学の場合と同じです.

  しかし,整数同士の演算には十分注意して下さい.例えば,
10.0 / 4.0 * 2.0		
と記述すれば,各定数は浮動小数点数として解釈され,10.0 を 4.0 で割った結果 2.5 に 2.0 が掛けられ結果は 5.0 になります.しかし,人間が計算する場合は同じであっても,
10 / 4 * 2		
と記述すると,各定数は整数として解釈され,10 を 4 で割った結果 2 (整数計算であるので,結果も整数になり,この段階で,小数点以下が切り捨てられる)に 2 が掛けられ,結果は 4 になります.これは,定数だけでなく変数を含む演算であっても同様です.

  同じような演算とその結果を以下に示します.なぜ,そのような結果になるかを十分理解してください.

演算 説明
7 / 3 * 3 7 / 3 * 3 = 2 * 2 = 6
7 / (3 * 3) 7 / (3 * 3) = 7 / 9 = 0
7 / 3 / 3 7 / 3 / 3 = 2 / 3 = 0

  ここで,演習問題をやってみます.各演算の結果について答えてください.

3.3.2 代入演算子

  プログラムによっては,演算した結果をどこかへ記憶しておき,その値を別の箇所で使用したいような場合がしばしば起こります.それを実現するのが代入演算子「 = 」です.代入演算子の左辺は必ず変数でなければなりません.例えば,前節の 2 つの演算結果を double 型変数 data 及び int 型変数 i_data に代入するためには,以下のように書きます.
data   = 10.0 / 4.0 * 2.0;
i_data = 10 / 4 * 2;		
  右辺で演算した結果と,代入する変数の型が異なる場合は,演算結果を代入する変数の型に変換した後,代入されます.しかし,情報が失われるような代入,例えば,x を int 型の変数とした場合,
x = 10.0 / 4.0;		
のような代入の場合,演算結果を int 型に変換した後,変数 x に代入しようとします.その結果,小数点以下が切り捨てられ(小数点以下の情報が失われ),x には 2 が記憶されることになります.そのため,C/C++ の場合は警告メッセージが出力されます.エラーではないので実行可能ですが,意図した結果でない場合も存在しますので,原則的には行わないようしにしてください.どうしても必要な場合は,後に述べる cast 演算子を利用してください.

  代入演算子は,一見,等号のように見えますが,等号ではないことに注意して下さい.例えば,
k = 2;
k = k + 3;		
という 2 つの文が順に実行される場合を考えてみます.まず,最初の文の実行により変数 k に値 2 が代入されます.次に,2 番目の文により,現在の変数 k の値( = 2 )と 3 を加えた結果 5 が変数 k に代入されます.したがって,この時点で,変数 k の値は 5 になっています.明らかに,等号とは異なることが分かると思います.

  また,ある変数に関する演算と,結果のその変数への代入を同時に行う演算子が存在します.例えば,上の 2 番目の例は,
k += 3;		
のようにも書けます.この演算子は,「-」,「*」,「/」,及び,「%」に対しても存在します.

  さらに,同じ値を複数の変数に代入したいとき,
x = y = z = 20.4;		
のような記述が可能です.

  先に述べたように,単に変数を定義した(型宣言した)だけでは,領域が確保されるだけであり,その変数に記憶されている値は未定です.例えば,プログラム
int x = 5, y;
x  = 3;   // 初期設定された 5 という値は失われる
x *= 5;
y  = x + 2;		
の 1 行目において,変数 x の値は初期値によって確定しますが,y の値は未定です.変数の値が決まるのは,代入,又は,後に述べる入力文によってその変数に値が入力されたときです.上に示すプログラム例では,4 行目の実行が終了した後,変数 y の値が確定( 17 )します.変数の値が確定する前に,その変数を参照するようなことは絶対に行ってはなりません.例えば,4 行目より前に,
x = y + 5;		
のように,y の値を参照するような演算を行うことはできません.

  各変数には,最後に代入または入力された値が記憶されています.ある変数に最後の代入または入力が行われた時点で,その変数( x )がそれ以前に記憶していた値はすべて失われます.例えば,3 行目が実行された時点で,初期設定された 5 や 2 行目で代入された 3 に関する情報は全て失われます.

  ここで,演習問題をやってみます.以下に示す順番で文が実行されたとき,4 行目の実行が終了した時点において,変数 x 及び y の値(変数 x 及び y に記憶されている値)について答えてください.
int x = 5, y;
x  = 3;
x *= 5;
y  = x + 2;		

3.3.3 インクリメント,デクリメント演算子

  1 だけ増やしたり減らしたりするのに,「++」(インクリメント演算子)や「--」(デクリメント演算子)といった演算子を使用できます.例えば,
k++;
n = 3 + m++;		
のような使い方をします.1 行目は,
k = k + 1;		
と同じ意味です.また,2 行目は,
n = 3 + m;
m = m + 1;		
と同じ意味です.上の例では,「++」を変数の後ろに付けましたが,これは,現在の値を演算に使用した後,「++」の付いた変数の値を 1 だけ増加させることを意味します.しかし,「++」を変数の前に付けると,その変数の値を 1 だけ増加させた後,演算に使用されます.例えば,
n = 3 + ++m;		
は,
m = m + 1;
n = 3 + m;		
と同じ意味になります.しかし,誤りの原因となりやすいため,「 n = 3 + m++; 」,「 n = 3 + ++m; 」のように,式内に ++ 演算子を記述するようなことは避けた方が良いと思います.演算子「--」についても,1 だけ減少させる点を除き,「++」と同様です.

  ここで,演習問題をやってみます.以下に示す順番で文が実行されたとき,4 行目の実行が終了した時点において,変数 x 及び y の値(変数 x 及び y に記憶されている値)について答えてください.
int x = 5, y = 7;
x--;
x--;
y++;		

3.3.4 型変換(キャスト(cast)演算子)

  演算は同じ型同士で行われ,また,代入も同じ型の変数に代入されるのが普通です.しかし,場合によっては,異なる型同士で演算したり,異なる型の変数へ代入したい場合が起こります.

  コンピュータは,基本的に,異なる型同士の演算を行うことができません.従って,そのような演算式が現れるとデータをいずれかの型に変換した後演算が行われます.例えば,
10.0 / 4;		
のような計算は,整数定数 4 を浮動小数点数に変換した後,演算が行われ,結果は,浮動小数点数になります(この場合は,2.5 ).一般に,複数のデータ型が混在した場合,変換によって失われる情報が少なくなることを目的として,以下に示すように,より上位の型に変換されます.
char < int < long < float < double < ・・・		
  また,代入の際は,代入すべき変数の型に変換され,代入が実行されます.例えば,db を double 型変数,k を int 型変数とします.このとき,
db = 10 / 3;
k  = 10.0 / 4.0;		
のような代入を行うと,最初の文では,整数 10 を整数 3 で割った結果 3 が,浮動小数点数( double 型)に変換され,変数 db には 3.0 が代入されます.また,2 番目の文では,演算の結果 2.5 が整数( int 型)に変換され,変数 k には小数点以下が切り捨てられた 2 が代入されます.この場合,C/C++ においては警告メッセージが出力されます.

  このように,異なる型の処理は自動的な型変換により実行できますが,場合によっては,思いもかけないことが起こります.また,自動的型変換により,自分自身の型宣言の誤りに気付かないまま実行されてしまう場合も,しばしば起こります.従って,できるだけ自動的な型変換は使用せず,明示的に型を変換した方が良いと思います.それを行うのが,キャスト演算子cast operator )です.キャスト演算子を変換したい定数または変数の前に付加して,希望の型に変換します.例えば,変数 db1,db2 を double 型とします.
db1 = 10.4;
db2 = (double)((int)db1 / 4)		
2 番目の文では,変数 db1 が int 型に変換された後,10 / 4 の整数演算が行われ,その結果が 2 となります.次に,整数 2 が double 型に変換され( 2.0 ),変数 db2 に代入されます.先の例「 k = 10.0 / 4.0; 」を,問題なく実行させるためには,「 k = (int)(10.0 / 4.0); 」と記述する必要があります.

  同じような演算とその結果を以下に示します.この例によって,キャスト演算子や自動的型変換について十分理解してください.

演算 説明
(double)(7 / 2) (double)(7 / 2) = (double)3 = 3.0
7 / (double)2 7 / (double)2 = 7 / 2.0 = 7.0 / 2.0 = 3.5
7 / 2.0 7 / 2.0 = 7.0 / 2.0 = 3.5
7 / 2 3

  ここで,演習問題をやってみます.以下の演算結果について,小数点以下第 1 位まで答えてください.

3.4 簡単なプログラム

  以上の説明により,入出力に関する項を除いて,簡単なプログラムが書けるはずです.この節では,2 つのデータを入力し,その和と差を出力するプログラムについて検討します.プログラムは,特別な命令が存在しない限り,書かれた順序に従って実行されていきます.以下に示すプログラム例では,この原則通り,最初の行から順に(実行可能な文が)実行されていきます.

  C/C++ のプログラムは,関数の集まりと言っても過言ではありません.プログラム例 3.1 に現れる printf や scanf も関数です.関数に関する詳細な説明は,後の章で行いますが,ある面で,数学の関数と非常に似ています.数学の関数は,その関数の中の変数に適当な値を代入すればそのときの関数値が得られます.C/C++ においても,例えば,正弦を計算する関数 sin(x) は,変数 x に適当な値を代入してやれば,その角度における正弦が計算されて返されます.ただし,printf や scanf のように,単に値を返すだけでなく,出力や入力といった複雑な処理を行う関数も多く存在します.

  完全に関数を理解することは,現在の段階では困難であり,また,printf や scanf という関数に対しても,初心者が誤って使用する例が多く見受けられます.そこで,C++ に興味がなくても,もし,C++ のコンパイラが手元にあるようでしたら,しばらくの間,入出力文だけはプログラム例 3.2 の方法を使用するのも良い方法かもしれません.

(プログラム例 3.1 ) 2 つのデータの和と差 ( A ~ C の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

(プログラム)
/****************************/
/* 2つのデータの和と差     */
/*      coded by Y.Suganuma */
/****************************/
#include <stdio.h>

int main()
{
	double sa, wa, x, y;
/*
		データの入力
*/
	printf("2つのデータを入力して下さい ");
	scanf("%lf %lf", &x, &y);
/*
		和と差の計算
*/
	wa = x + y;
	sa = x - y;
/*
		結果の出力
*/
	printf("和は=%f 差は=%f\n", wa, sa);

	return 0;
}
			
1 ~ 4 行目

  プログラム全体に対する注釈です.注釈は,人間がプログラムを読む際,理解しやすくするためのものであり,コンパイラ等によって特別な処理はされません.プログラムを実行するのはコンピュータですが,プログラムを書いたり修正したりするのは人間です.従って,プログラムを書く際に最も注意すべきことは,如何に読み易く,かつ,分かり易いプログラムを書くかという点です.できるだけ多くの注釈を入れておいて下さい.そのことにより,他の人がプログラムを理解しやすくなると共に,プログラム上のエラーも少なくなるはずです.

  C/C++ の場合,/* と */ で挟まれた部分は,注釈とみなされます.従って,10~12 行目,15~17 行目,及び,20~22 行目も注釈であり,プログラムの該当する部分における処理内容を説明しています.

5 行目

  # で始まる文は,プリプロセッサ(第 9 章参照)により処理され,結果がコンパイラに渡されます.#include は,ヘッダファイル stdio.h の取り込みを行います.C/C++ では,関数を多く使用します.例えば,13,14 行目の printf,scanf もシステムが用意した関数です.これらの関数を使用するためには,使用するに先立って,様々な宣言等を行う必要があります.その宣言等を自分で書くのは面倒なため,システムには,使用する関数毎に必要な宣言を記述したファイルが準備されており,それをヘッダファイルと呼びます.関数によってどのようなヘッダファイルを必要とするかは,マニュアル等に書いてありますので,その都度必要なヘッダファイルを記述して下さい.stdio.h は,関数 printf や scanf を使用するために必要なヘッダファイルであり,プログラムを作る場合,この行を常に付加しておいた方が良いと思います.

  なお,ヘッダファイルを自分で作成することもできます.

7 行目

  プログラムの最初であることを表します.8 行目の { と 26 行目の } に囲まれた部分がプログラムの本体になります.従って,7,8,25(省略しても構わない),及び,26 行目は,C/C++ のプログラムにとって常に必要となります.なお,void は,外部からこのプログラムに渡す情報(引数)がないことを意味しています(省略可能).また,int は,このプログラムの処理を行った後,int 型の値を 25 行目の return 文によって外部に返すことを意味しています.詳細については,「簡単な関数」を参照してください.

  また,プログラムの本体に当たる 9 行目から 25 行目までは,段落が下げて(字下げして)書かれていますが,これも,プログラムを読みやすくするための一つの手段であり,必ず,このように,段落を下げて書いて下さい(どの程度下げるかは任意ですが,タブを使用する方法が一般的です).

9 行目

  プログラムで使用する変数の型を宣言している型宣言文です.変数 sa,wa,x,及び,y が double 型であることを宣言しています.初期値の指定を行っていませんので,この段階では 4 つの変数の値は未定となります.また,この文のように,一般的に,C/C++ における一つの文の終わりにはセミコロン( ; )を付ける必要があります.なお,ここで型宣言を行わず,14 行目の前,つまり,変数 x や y が使用される前のいずれかの位置で,
    double x, y;			
のような型宣言を行っても構いません,また,変数 sa,wa に対しては,ここで型宣言を行わず,18,19 行目を以下のように記述しても構いません.
	double wa = x + y;
	double sa = x - y;			
13 ~ 14,23 行目

  13,14 行目は,2 つのデータを入力するための文です.単に,入力のためだけなら,14 行目の scanf だけで十分ですが,その場合,何のメッセージも出力されずキーボードからの入力待ちになってしまうため,一見コンピュータが止まってしまったように感じます.また,多くの入力を要求するような場合は,scanf だけでは,どの入力を要求しているのかが分かりません.そのため,13 行目の printf が使用されています.

  標準入出力装置(一般的には,キーボードとディスプレイ)に対して入出力を行う場合,対象とするものは文字列です.キーボードから入力する場合,たとえ数値であっても,2 進数を使用したコンピュータの内部表現ではなく,例えば 123.45 のように,我々が読むことができる文字列として入力します.しかし,数値データを,入力された文字列としてそのまま記憶したならば,演算等を行うことができません.そのため,入力された文字列をコンピュータ内部で使用する表現方法に変換して記憶してやる必要があります.例えば,123.45 という文字列を数値として扱いたければ,浮動小数点表現に変換して記憶しておく必要があります.もちろん,123.45 を文字列として内部的に扱いたければ,文字列として記憶しておく必要があります.

  また,ディスプレイに出力する場合も,メモリ(変数)に記憶されているデータを文字列に変換して出力します.さもなければ,我々は,0 と 1 の並びとして出力される結果を自分自身で解釈しなければなりません.次に示すプログラム例のように,C++ における cin や cout を使用する場合は,これらの変換を自動的に行ってくれますが,scnaf や printf を使用する場合,これらの変換方法を指定してやる必要があります.

  例えば,scanf は,以下のようにして使用します(以下の説明において,char 部分に対する説明は,ここでは無視して下さい).
    double d_data;
    int i_data;
    char c_data[10];
    scanf("%lf %d %s", &d_data, &i_data, c_data);			
"%lf %d %s" の部分が,入力されたデータをどのように変換するかを指定する部分です.% に続く文字列が 3 つありますので,3 つのデータが入力されることを意味します.入力された文字列に対して,%lf は double 型( float 型は %f,long double 型は %Lf )の浮動小数点表示に変換して,%d は int 型( long int 型は %ld であるが,int 型と long int 型のサイズが等しいときはいずれも %d とする.また,long long int 型は %lld となる)の整数に変換して,また,%s は文字列としてそのまま,記憶することを意味しています.これら 3 つの % で始まる文字列は,次に続く 3 つのデータに順番に対応していますので,この scanf 関数に対して,例えば,
    3.14 123 abc			
のように入力すると,d_data に 3.14 が double 型に変換され,i_data に 123 が int 型に変換され,また,c_data に文字列 "abc" が,記憶されます.各変数に対して,そのアドレスを指定しなければならない(アドレスについては,後の章で説明します.ここでは,変数に & 記号が付くという程度で理解しておいてください)点に注意してください.

  printf は,scanf とは逆に,記憶されたデータを文字列に変換する操作を行います.例えば,以下のようにして使用します.
    double d_data;
    int i_data;
    char c_data[10];
      ・・・・・
    printf("結果は %f %10.3f %d %5d %s\n", d_data, d_data, i_data, i_data, c_data);			
この結果,まず,"結果は" という文字列が出力されます.printf においては, % で始まる文字列とエスケープシーケンス(後述)以外は,記述された内容がそのまま出力されます.次に,以下の順序で 5 つのデータが出力されます(各データ間には,1 つのスペースが入る).

  1. %f は double 型( %Lf は long double 型)のデータを固定小数点表現の文字列に変換します.なお,1.23x10-3 のような表現方法に対応する 1.23e-03 という方法-浮動小数点表現-も存在します( %e,%Le).% と f の間に何も記述しなければ,全体の桁数小数点以下の桁数がシステムの標準形式に従います.この場合,d_data の内容が,システムの標準形式に従って出力されます.
  2. 最初のデータと変換方法は同じですが,この場合は,出力形式を指定しています.d_data の内容が,小数点以下 3 桁,全体の桁数 10 桁で出力されます(例: △△△-12.345 ).桁数が 10 桁に満たない場合は,左側にスペースが挿入されます.全体の桁数を指定しない場合は,10 の部分を省略しても構いません.
  3. %d は int 型( long int 型は %ld であるが,int 型と long int 型のサイズが等しいときはいずれも %d とする.また,long long int 型は %lld となる)のデータを文字列に変換します.% と d の間に何も記述しなければ,システムの標準形式に従って出力されます.この場合,i_data の内容が,システムの標準形式に従って出力されます.
  4. 上の i_data と変換方法は同じですが,この場合は,出力形式を指定しています.i_data の内容が,全体の桁数 5 桁で出力されます(例: △△-12 ).桁数が 5 桁に満たない場合は,左側にスペースが挿入されます.
  5. c_data の内容が文字列として出力されます.なお,1 文字に対する入出力には,%c を使用します.

  以上の説明に従うと,13 行目の printf は,入力を促すメッセージを出力するだけです.23 行目では,wa と sa の値を出力しています.23 行目の " の中の最後の記号 \n も 1 文字を表し,そのまま出力されますが,\ の付いた記号は,「エスケープシーケンス(escape sequence)」といって,特別な働きをします.例えば,\n が出力されると改行が行われます.

  14 行目の scanf では,キーボードから入力された 2 つのデータが変数 x 及び y に代入されます.なお,このとき,"2つのデータを入力して下さい" というメッセージに続いて,2 つのデータを半角スペースで区切って 1 行で入力しても,また,2 つのデータを改行で区切って 2 行に渡って入力しても構いません.ここで初めて,2 つの変数の値が確定することになります.もちろん,この時点では,まだ,変数 wa,及び,sa の値は未定のままです.この関数では,各変数の前に & を付加する必要があることに注意して下さい.

18 ~ 19 行目

  これらの文では,見て明らかなように,和と差の計算をし,結果を変数 wa と sa に代入しています.その結果,18 行目で変数 wa の値が,また,19 行目で変数 sa の値が未定ではなくなります.変数 x,及び,y に対しては,それらの値が参照されているだけですので,14 行目で確定した値がそのまま保たれています.

  一般的に,変数の値が変化する(記憶されている値が破壊される)のは,その変数に対して,代入,または,入力が実行された場合だけです.たとえば,19 行目以降で,変数 sa に対して,
    scanf("%lf", &sa);			
または,
    sa = 20;			
のような文が実行されると,19 行目で代入された値は失われ,新たに入力された値(最初の文),または,代入された値( 2 番目の文,この場合は,20 )が,変数 sa の値として記憶されます.

  このプログラムを実行し,5 と 3 を入力すると,以下のような結果が得られます.
    和は=8.000000 差は=2.000000			

(プログラム例 3.2 ) 2 つのデータの和と差(cout,cin)(C++) ( A ~ C の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)

  プログラム例 3.1 と全く同じ内容を C++ で使用できる入出力方法を使って書いてみました.初心者は,printf や scanf の使用に際し,特にデータ型の不一致が原因である誤りをよく起こします.そのため,結果が正しく出力されなかったり,場合によっては,プログラム自身を破壊してしまうことも少なくありません.このプログラムの入出力文では,変数の型を考慮せず,単に変数を並べるだけで入出力が行えるようになっています.なお,cin や cout については,16.1 節を参照してください.

(プログラム)
/****************************/
/* 2つのデータの和と差     */
/*      coded by Y.Suganuma */
/****************************/
#include <iostream>
using namespace std;
int main()
{
	double sa, wa, x, y;
/*
		データの入力
*/
	cout << "2つのデータを入力して下さい ";
	cin >> x >> y;
/*
		和と差の計算
*/
	wa = x + y;
	sa = x - y;
/*
		結果の出力
*/
	cout << "和は=" << wa << " 差は=" << sa << endl;

	return 0;
}
			
  このプログラムは,プログラム例 3.1 と,5 行目のヘッダファイル,6 行目,及び,13,14,23 行目の入出力文が異なっているだけです.以下に現れるプログラムにおいても,上の箇所だけを修正してやれば,全く同じように実行できるはずです.なお,23 行目の endl は,改行を意味し,"\n" または '\n' と記述しても構いません.

  6 行目は,使用する名前空間を定義するための文です.名前空間については,7.2.3 節を参照してください.なお,この文を書かずに,cin,cout,endl 等の前に,たとえば,

std::cout

のように,「 std:: 」を付加しても構いません.

  先の例と同様に,14 行目を,以下のように,2 行に分けて書くこともできます.

   cin >> x;
   cin >> y;

また,scanf を使用する場合とは異なり,変数 x や y が,int 型の変数であっても,記述方法は全く同じです.

  cout に関しても,変数の型を気にすることなく同じように記述できます.cout では,「 << 」で挟まれた部分が順に出力されていきます.「 " 」,または,「 ' 」で囲まれた部分(「 ' 」で囲むのは 1 文字に限る)はそのまま出力され,定数や変数は,その型に対応した変換が自動的に行われて出力されます.

  重要なことですので,再度述べておきます.上で述べたいずれの例においても同様ですが,ある変数に対して初期値を指定しない型宣言を行うと,その変数に対応した記憶場所は確保されますが,その値は未定です.変数の値を確定するためには,「型宣言文で初期値を指定する」,「代入演算子によってその変数に値を代入する」「入力文によって,その変数に値を入力する」などの処理が必要です.また,代入や入力処理が行われると,その変数にそれまで記憶されていた内容は失われます.

  以下に示す表では,入力データとして 5 を入力した場合,プログラムの各行が実行された後に変数 x 及び y の値がどのようになっているかを示しています( - は値が未定であることを示す).このように,書かれたプログラムを読み,そのプログラムがどのような順序で実行され,かつ,変数の値がどのように変化していくかを確認することは,プログラムを書く上で非常に重要な作業になります.今後,プログラムを書く際は,必ず行ってください.

実行順序 プログラム x の値 y の値
1 int x, y = 10; - 10
2 scanf("%d", &y); - 5
3 x = y + 3; 8 5
4 x *= 5; 40 5
5 printf("%d\n", x); 40 5

3.5 その他

3.5.1 キーワード

  C のキーワードkeyword ),及び,その簡単な説明です.これらのキーワードを変数名,関数名等に使用することはできません.
keyword 説明 keyword 説明 keyword 説明 keyword 説明
_Alignas アライメント _Atomic マルチスレッド _Bool データ型 _Complex 複素数型
_Generic 型ジェネリック _Imaginary 複素数型 _Noreturn 関数指定子 _Static_assert アサート
_Thread_local マルチスレッド auto データ型,記憶クラス alignof アライメント break ループから脱出
case 条件分岐 char データ型 const 変更不可 continue 繰り返し
default デフォルト do 繰り返し double データ型 else 条件分岐
enum 列挙型 extern 外部参照 float データ型 for 繰り返し
goto ジャンプ if 条件分岐 inline インライン関数 int データ型
long データ型 register レジスタ restrict ポインタ参照 return 関数からの戻り
short データ型 signed データ型 sizeof データサイズ static 静的
struct 構造体 switch 条件分岐 typedef データ型の別名 union 共用体
unsigned データ型 volatile 最適化の抑止 void 引数無し while 繰り返し

---------------------(C++)キーワード-------------------------

keyword 説明 keyword 説明 keyword 説明 keyword 説明
alignas アトリビュート alignof アライメント asm 処理系依存 and &&,代替表現
and_eq &=,代替表現 auto データ型 bool データ型 bitand &,代替表現
bitor |,代替表現 break ループから脱出 case 条件分岐 class クラス
char データ型 char16_t データ型 char32_t データ型 catch 例外処理
compl ~,代替表現 const 変更不可 const_cast キャスト constexpr 定数式
continue 繰り返し decltype 型を取得 default デフォルト delete 動的記憶域
do 繰り返し double データ型 dynamic_cast 動的キャスト else 条件分岐
enum 列挙型 explicit 暗黙の型変換不許可 export 予約 extern 外部参照
false final 派生禁止,文脈依存 float データ型 for 繰り返し
friend フレンド goto ジャンプ if 条件分岐 inline インライン関数
int データ型 long データ型 mutable 書き換え可能 namespace 名前空間
new 動的記憶域 noexcept 例外指定 not !,代替表現 not_eq !=,代替表現
nullptr ヌルポインタ operator 演算子多重定義 or ||,代替表現 or_eq |=,代替表現
override オーバーライド,文脈依存 private アクセス制御 protected アクセス制御 public アクセス制御
register 予約 reinterpret_cast キャスト return 関数からの戻り short データ型
signed データ型 sizeof データサイズ static 静的 static_assert 表明
static_cast キャスト struct 構造体 switch 条件分岐 template テンプレート
this 自分自身へのポインタ thread_local スレッドローカル throw 例外処理 try 例外処理
true typedef データ型の別名 typename テンプレート引数 typeid RTTI
union 共用体 unsigned データ型 using 名前空間 virtual 仮想関数
volatile 最適化の抑止 void 引数無し wchar_t データ型 while 繰り返し
xor ^,代替表現 xor_eq ^=,代替表現        

----------------------(C++)キーワード終わり--------------------

3.5.2 アスキーコード

  アスキーコードASCII code )表です
000 ^@ (nul) 016 ^P (dle) 032 (sp) 048 0 064 @ 080 P 096 ` 112 p
001 ^A (soh) 017 ^Q (dc1) 033 ! 049 1 065 A 081 Q 097 a 113 q
002 ^B (stx) 018 ^R (dc2) 034 " 050 2 066 B 082 R 098 b 114 r
003 ^C (etx) 019 ^S (dc3) 035 # 051 3 067 C 083 S 099 c 115 s
004 ^D (eot) 020 ^T (dc4) 036 $ 052 4 068 D 084 T 100 d 116 t
005 ^E (enq) 021 ^U (nak) 037 % 053 5 069 E 085 U 101 e 117 u
006 ^F (ack) 022 ^V (syn) 038 & 054 6 070 F 086 V 102 f 118 v
007 ^G (bel) 023 ^W (etb) 039 ' 055 7 071 G 087 W 103 g 119 w
008 ^H (bs) 024 ^X (can) 040 ( 056 8 072 H 088 X 104 h 120 x
009 ^I (tab) 025 ^Y (em) 041 ) 057 9 073 I 089 Y 105 i 121 y
010 ^J (lf) 026 ^Z (eof) 042 * 058 : 074 J 090 Z 106 j 122 z
011 ^K (vt) 027 ^[ (esc) 043 + 059 ; 075 K 091 [ 107 k 123 {
012 ^L (np) 028 ^\ (fs) 044 , 060 < 076 L 092 \ 108 l 124 |
013 ^M (cr) 029 ^] (gs) 045 - 061 = 077 M 093 ] 109 m 125 }
014 ^N (so) 030 ^^ (rs) 046 . 062 > 078 N 094 ^ 110 n 126 ~
015 ^O (si) 031 ^_ (us) 047 / 063 ? 079 O 095 _ 111 o 127 

3.5.3 エスケープシーケンス

  記号(\)とそれに続く文字または数字の組み合わせをエスケープシーケンスEscape Sequence )と呼びます.文字定数の一種であり,端末やプリンタ上でのキャリッジリターンやタブなどの動作を指定するために使います.また,ダブルコーテーションマーク(")など,通常は特別な意味を持つ文字や,出力できない文字を表すときにも使用します.C/C++ のエスケープシーケンスは,次のとおりです.
Seq. 説明 Seq. 説明
\a ベル \? リテラル クオーテーション
\b バック スペース \' シングル クォーテーション
\f 改ページ \" ダブル クォーテーション
\n 復改 \\ 円記号
\r 改行 \ddd 8進表記による ASCII 文字
\t 水平タブ \xdd 16進表記による ASCII 文字
\v 垂直タブ    

演習問題3

[問1]以下の演算を C/C++ のプログラム内で実行した結果を答えよ.
(1)4.0 / 5.0
(2)4 / 5
(3)(double)4 / 5
(4)(double)(4 / 5)
(5)(int)(4.0 / 5.0)
(6)(20 / 5) * (19 / 4)
(7)(20.0 / 5.0) * (19.0 / 4.0)
(8)20 / 5 * 19 / 4

[問2]台形の上底 t1,下底 t2,及び,高さ h の値を,それぞれ,3.5,1.0,及び,0.7 としたとき(これらの値は,各変数に代入または初期設定せよ),台形の面積を計算し,出力するプログラムを書け.

[問3]円の半径を読み込み,その円の円周と面積を出力するプログラムを書け.

[問4] x の値を読み込み,次の各関数の値( y )を出力するプログラムを書け.
(1)y = x3 + 3x2 + 2
(2)y = (x + 3)2 / 3 + 5

[問5] 2 つの整数データを読み込み,商と余りを出力するプログラムを書け.

[問6]千円札だけを使用でき,かつ,千円以下の切符を売る自動販売機がある.任意の料金( 10 円単位)の切符を買った(切符の料金を入力データとして読み込む)とき,その釣り銭を出力するプログラムを書け.ただし,釣り銭の総額だけでなく,必要な硬貨の枚数,例えば,500 円硬貨 1 枚,100 円硬貨 2 枚,50 円硬貨 1 枚,10 円硬貨 3 枚という結果も出力すること.
(ヒント)例えば,「 turi / 500 」という演算により,500 円硬貨の枚数が得られる

[問7]ある値段(入力)の商品を購入したとき,消費税( 3 %)を含めた実際の支払価格を以下の 3 つの場合について計算し,それぞれの値を出力するプログラムを書け.ただし,浮動小数点数を使用すると誤差が生じる可能性があるので,すべて整数を使用して計算せよ.
(1)1 円未満を切り捨てる
(2)1 円未満を切り上げる
(3)1 円未満を4捨5入する
(ヒント)例えば,切り捨ての演算は,「nedan * 103 / 100」という演算により可能

情報学部 菅沼ホーム 全体目次 演習解答例 付録 索引