本実験を通し,C言語の基礎的なコーディングの仕方とフローチャートを通しプログラミングで必要な論理的な思考を身につけることを目標とする.
- 必ず筆記用具,実験書,プログラミング(C言語)の教科書を持ってくること.
- 注意事項は 注 ,発展的内容には 発展 と書かれている.
- 発展と書いてある問題は,時間がある場合取り組む.
課題でソースコードを提出する場合は,次のようにソースコードの上部に番号,名前,課題番号,提出日を書いてください.ソースコードは,レポート用紙にホッチキスで止めて出してください.その時,レポート用紙を表紙にしてください.
/*
xx番 情報 太朗
課題 1.1
提出日 xxxx年xx月xx日
*/
#include <stdio.h>
int main(void)
{
return(0);
}
注 #include <stdio.h>,return(0)は今のところ呪文だと思っておこう.
注 /*コメント*/はコメントと呼ばれ,/* */で囲まれた部分は実行されない.そのため,ソースコードの注意事項やメモ,もしくは一時的に無効にしたいコードを/* */の中身に書く.
発展 C言語ではint main(void)と書く. C++ではint main()でもよい.引数が空の場合の挙動がCとC++では違うため(C++では引数が空の場合void).
プログラミングでは,普段使うことがない様々な記号が使われる.それぞれの読み方を覚えておかないと,教員や友人との意思疎通が難しくなる.ここでは,プログラミングでよく使われる記号とその読み方の一覧を示す.なお,バックスラッシュはWindowsの日本語環境では円マークとして表示される事があるので注意する.
記号 | 読み方 |
---|---|
. | ピリオド,ドット |
, | コンマ,カンマ |
/ | スラッシュ |
\ | バックスラッシュ |
¥ | 円マーク |
' | クォーテーション |
" | ダブルクォーテーション |
: | コロン |
; | セミコロン |
! | エクスクラメーションマーク |
& | アンパサンド |
# | シャープ |
@ | アットマーク |
~ | チルダ |
* | アスタリスク |
- | ハイフン |
_ | アンダースコア |
プログラミングは最も重要なのは,読みやすいコードを書くことである.読みにくいコードは,どのような処理を行うコードか分かりづらく,その結果バグを生みやすい.さらに,バグが有り修正する場合,読みにくいコードでは修正したくてもどこを修正すべきか苦労して探すことになる.次の事項に注意すれば読みやすいコードを書くことができる.皆もこの実験から読みやすいコードを書くことを心がけよう.
- コメントを書く.
- インデント(字下げ)をする.そして,そのインデントのルールはコード内で変えない.
- マジックナンバーをなくす.
- 変数名,関数名,クラス名などを分かりやすいものにする(命名規則を統一する,途中で変えない).
- 分かりやすい表現(処理)を使う.
- コードを機能別に関数,クラス,ファイル等に分ける.
発展 字下げのルールや括弧の位置など,コーディングの見た目に関わるルールをコーディングスタイルという.コーディングスタイルには,K&Rスタイル,GNUスタイルなどあり参考にすると良い.ただし,どれがかが正しいというものではないので,個人でプログラミングを楽しむ場合,プログラマの好みで選べば良い.
プログラミングでは扱うデータに種類がある.それぞれの特徴を知らなければ,正確に動作するプログラムは作れない.本実験では,簡単な四則演算と変数の型について理解を深めることを目的とする.
変数とは,プログラム内で数値や文字を保存するための入れ物である.変数にはいくつかの種類がある.C言語で扱う変数は大きく整数型,浮動小数点型,文字型の3種類である.整数型の変数には整数を,浮動小数点型の変数には自然数を,文字型には文字を格納することができる.プログラミングでは,これらの変数型を用途に応じ適切に使い分ける必要がある.初心者である諸君は,まず,整数型int,浮動小数点型double,文字型charの3種類を覚えておこう.C言語で用いることができる変数型の一部を表に示す.int,double,char以外にも型があることを知っておこう.
発展 char型は整数型でもある.また,int,longなど環境によって使える桁数が変わる変数型がある.
発展 符号なし(正の値)の変数も作ることが可能である.その場合は方の前にunsignedと書く.例えば,125から-125まで使える変数型の場合はunsignedの場合0から256までの使える.
発展 現在x86 CPU向けの一般的なプログラムを書くとき,floatを使う意味はほぼないと考えられる.なぜならば,float型のほうが精度が悪い一方で計算速度が上がらないからである.そのため,本実験では浮動小数点型にdoubleを用いている.しかし,floatにメリットが無いわけではなく,データ転送がボトルネックとなるソフトウェアで用いればfloatはデータ量が半分のため速度向上が見込めるし,floatの計算が圧倒的に速いハードウェア向けのソフトウェアにfloatを用いればdoubleに比べ圧倒的な速度向上が見込める.このようにfloatについて簡単に議論したが,floatの扱いや演算に関する事柄はCPU・GPUレベル,アセンブリコードレベル,アルゴリズムレベル,システムレベルなど広範囲に関わってくる.そのためfloatに関しての深入りは,高専・大学のC言語の講義の範疇を超えている.
データ型 | データ型の名称 | 範囲(環境によって変わる) |
---|---|---|
char | 符号付き8bit整数型 | -128 から 127 |
short | 符号付き短整数型 | -32,768 から 32,767 |
int | 符号付き整数型 | -2,147,483,648 から 2,147,483,647 |
long int | 符号付き長整数型 | -2,147,483,648 から 2,147,483,647 |
long long | 符号付き長長整数型 | – 9,223,372,036,854,775,808 から 9,223,372,036,854,775,807 |
float | 単精度実浮動小数点型 | 3.4E+/-38 (有効桁7桁) |
double | 倍精度実浮動小数点型 | 1.7E+/-308 (有効桁15桁) |
char | 文字型 |
変数a,b,c,d, eを,aはchar型,bとcはint型,dとeはdouble型で宣言した例をリスト1.1に示す.
1 /*リスト1.1*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 /*宣言*/
7 char a;
8 int b, c;
9 double d;
10 double e = 2.7;
11
12 /*変数に文字もしくは数を入れる。*/
13 a = 'X';
14 b = 10;
15 c = 100;
16 d = 1.1;
17
18 return(0);
19 }
変数の宣言は
データ型 変数名;
の形式で行う.同じ型の変数を宣言するときは"int b, c;"のように一行に書くことができる(もちろん一つづつ宣言しても良い).また,変数を宣言すると同時に初期化したい場合も,"double e = 2.7;"のように一行で書くことができる.
変数に値を代入する場合は
変数名 = 値;
というように書く.
課題1.1 次の問に答えよ.
- 文字列を扱う場合,どの型を用いればよいか答えよ.
- 最も精度が高い(使える桁数が多い)四則演算を行いたい場合,どの型を用いればよいか答えよ.
- 最も長い桁を表現できる整数型はどれか答えよ.
C言語では画面にデータを表示する場合,よくprintfが用いられる.printfの使い方は次のとおりである.
printf("文字列と変換指定子", 変数);
printf関数は"(ダブルクォーテーション)でくくられた部分を画面に表示する.そして,変数と書かれた部分に表示したい変数を書くと表示される.ただし,変数に対応した変数指定子をダブルクォーテーション内に書く必要がある.ダブルクォーテーション内に書かれた文字列はそのまま表示される.また,変数の部分は省略することができる.リスト1.2に使用例を示す.
1 /*リスト1.2*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 int i = 16;
7 double f = 3.14;
8 char c1 = 'A';
9 char *c2 = "Hello";
10
11 printf("printfの使い方\n");
12
13 /*変数の表示*/
14 printf("整数 %d\n", i);
15 printf("浮動小数点数 %f\n", f);
16 printf("文字 %c\n", c1);
17 printf("整数 %d\n", c1);
18 printf("文字列 %s\n", c2);
19 printf("8進数 %o\n", i);
20 printf("16進数 %x\n", i);
21
22 /*変数と変数指定子の型が異なった場合*/
23 printf("整数 %f\n", i);
24 printf("浮動小数点数 %d\n", f);
25
26 return(0);
27 }
注 環境により(バックスラッシュ)が¥(円マーク)として表示される(扱われる)場合がある.ただし,\と¥を区別する(別の文字として扱われる)環境もあるので注意が必要である.詳しく知りたい人は,円マークと文字コードの関係を調べてみるとよい.
このサンプルを見ると2つほど見慣れない表現が使われている.一つは%を使ったもの,もう一つは(バックスラッシュ)を用いたものである.%を用いたものは,変数指定子とよばれ,変数の中身を表示するために使われる.例えば,サンプルプログラムで用いられているprintf("整数 %d\n", i)の%dはダブルクォーテーションの外の整数型の変数iの中身を表示するために用いられる.printfで変数の中身を表示するとき,その変数の型に対応した変換指定子を用いないと適切に表示されない.バックスラッシュを用いたものは,エスケープシークエンスと呼ばれるもので,改行やタブなど特殊な文字を表示するために用いられる.
変換指定子 | 意味 |
---|---|
%c | 1文字出力する |
%s | 文字列を出力する |
%d | 整数を10進数で出力する |
%o | 整数を8進数で出力する |
%x | 整数を16進数で出力する |
%f | -dddd.ddddddの形式で出力する |
エスケープシーケンス | 意味 |
---|---|
\n | 改行を表示する |
\t | タブを表示する |
\a | 警報音 |
課題1.2 リスト1.1を変数a,b,c,d,eを表示するように変更せよ.変更した行のみ報告せよ.
課題1.3 リスト1.2を実行し,表示結果を答えよ.表示結果のなかで表示された数値が間違っているものを挙げ,なぜに間違った値が表示されたのか答えよ.
ここでは,C言語で四則演算を行うための演算子を学ぶ.プログラムで四則演算を行うために用いる文字のことを算術演算子と呼ぶ.主に使う算術演算子を表に示す.加減乗除は,算数でよく使うため諸君は理解できると思うが,剰余算は初めて見るかもしれない.剰余算とは,整数を整数で割った時の余りを計算することである.プログラミングでは剰余算はよく使うので理解しておこう.算術演算子を用いたサンプルコードをリスト1.3に示す.
演算子 | 意味 |
---|---|
+ | 加算 |
- | 減算 |
* | 乗算 |
/ | 除算 |
% | 剰余算 |
1 /*リスト1.3*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 double x, y, z;
7 x = 1;
8 y = 2;
9 z = x / y;
10
11 printf("%f\n", z);
12
13 return(0);
14 }
リスト1.3では,1/2=0.5のように我々が習ってきた算数と相違ない結果が表示された.実は,算数と同じ結果が出たのは変数型を適切に用いたからである.次のリスト1.4に,適切に計算出来ないソースコードを示す.課題を行い,理解して欲しい.
1 /*リスト1.4*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 int x, y;
7 double z;
8 x = 1;
9 y = 2;
10 z = x / y;
11
12 printf("%f\n", z);
13
14 return(0);
15 }
課題1.4
- リスト1.4を実行した場合に表示される値を報告せよ.
- リスト1.3とリスト1.4のソースコードの違いを報告せよ.
- リスト1.4のxとyの数値をいろいろ変えることで出力される値の規則性を見つけ,それを報告せよ.例えば,x=1.9,x=2.1,x=3,x=3.9,x=4に変えてみる.
計算に応じ変数型を適切に用いないと,正確な計算ができない.四則演算を正しく行うためには,浮動小数点数を用いる必要がある.初めから変数が浮動小数点型であれば四則演算の結果は浮動小数点数となるが,整数型変数の四則演算の結果は整数となる.しかし,整数型変数ではあるが四則演算の結果は浮動小数点数としたい場合もあるだろう.その場合,型変換(キャスト)を行う必要がある.キャストを用いた例をリスト1.5に示す.リスト1.4と1.5の違いは,x / yの前に(double)が追加されたところとだ.(double) x / yは,まず変数xをdouble型に変換する(double) xという計算が実行され,double型に変換されたxをyで割っている.浮動小数点数と整数の計算は浮動小数点数になるというC言語の性質を利用している.
1 /*リスト1.5*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 int x, y;
7 double z;
8 x = 1;
9 y = 2;
10 z = (double) x / y;
11
12 printf("%f\n", z);
13
14 return(0);
15 }
課題1.5 リスト1.6を型変換を利用し計算が正しく行われるよう変更せよ。変更した行のみ報告せよ.
1 /*リスト1.6*/
2 #include<stdio.h>
3
4 int main(void)
5 {
6 int x = 1;
7 int y = 4;
8 double z;
9
10 z = x/y + 1.5;
11
12 printf("%f", z);
13
14 return(0);
15 }
課題1.6 リスト1.7を実行し,その出力結果を報告し,その結果を考察せよ.
1 /*リスト1.7*/
2 #include<stdio.h>
3
4 int main(void)
5 {
6 int a = 1;
7 int b = 2;
8
9 printf("%f\n", (double) a / b);
10 printf("%f\n", a / (double) b);
11 printf("%f\n", (double) (a / b) );
12
13 return(0);
14 }
前節では正しい型を使わないと正確な計算ができないと説明した。しかし、計算結果に小数点以下が必要にない場合,あえて整数型を用い四則演算する場合がある.リスト1.8に具体例を示す.リスト1.8は任意の金額を500円玉で払うためには何枚必要かを求めるプログラムである.枚数を求める計算は11行目書かれている.11行目の計算を詳しく見てみよう.kingaku/500は整数型同士の割り算なので結果は整数型となる.kingaku=700とあるから700/500=1となる.これでは1枚足りないので,この割り算の結果に1足されている.
1 /*リスト1.8*/
2 #include <stdio.h>
3
4 int main(void)
5 {
6 int kingaku;
7 int maisuu;
8
9 kingaku = 700;
10
11 maisuu = kingaku/500 + 1;
12
13 printf("%d円払うためには500円玉%d枚必要です.", kingaku, maisuu);
14
15 return(0);
16 }
課題1.7 (発展) リスト1.8を参考に,任意のお釣り(日本円)を払うとき,そのお釣りの紙幣と貨幣の枚数の総和を最も小さくする払い方(各紙幣と貨幣の枚数)を表示させるプログラムを作成せよ.
課題1.8 (発展) 昔のゲームではキャラクタの能力値の上限が255のものがあった.C言語でなるべくメモリを節約しつつ255が上限の変数を使う場合,どの型を用いればよいか.
課題1.9 (発展) 変数が取り扱える数値の範囲は,環境により変わる場合がある.32bit環境と64bit環境で,変数が取り扱える数値の範囲にどのような違いがあるか調べて報告せよ.