わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

C言語について,知っておくとよいこと

 「C言語」はしばしば「C」と書かれます.
 Cのプログラムのファイルは,ソースファイルと呼ばれます.コンパイルにより実行ファイルを生成して,それを実行します*1.ソースファイルを作成(編集)するのは「テキストエディタ」なのに対し,コンパイルを含むコマンド実行を行うのは「端末」「シェル」です.
 授業で最初に打ち込んでもらっているソースファイルは以下のとおりです.

#include <stdio.h>

int main(void)
{
  printf("Hello, World!\n");

  return 0;
}

 先頭行に「#include <stdio.h>」を書くのが慣例です.これにより,printf関数が使えます.「#include <studio.h>」と書いてはいけません.stdioはSTanDard Input/Output(標準入出力)に由来します.
 文は原則として「;」で終えます.記号にはそれぞれ意味があります.コロン(:)とセミコロン(;),コンマ(,)とピリオド(.),対になる記号 ( ) { } [ ] " " などを間違えると,コンパイルのときにエラーが出て,実行ファイルが作られません.
 上のソースファイルは,「main」という名前の関数(main関数)を定義します.実行するためのプログラムでは,main関数を必ず一つだけ定義します.「int main(void)」の行について,授業ではどのプログラムもこの書き方でしたが,カッコ内は,コマンドライン引数*2を取り入れるプログラムになると変わってきます.
 「{」から「}」までが,main関数の内容です.「Hello, World!」と改行(「\n」は改行を意味します)を出力---画面に表示---し,プログラムを終了します.「return 0;」を書くのは,main関数の前がint(整数型の値を「返す」という関数)だからです.
 変数を使用することで,より複雑な処理を行うことができます.宣言文では型名も指定します.以下は変数宣言のコード例です.aとcとd1とd2が変数名,intとcharとdoubleが型名です.

int a;
char c;
double d1, d2;

 変数宣言の際,変数名の直後に「= 値」を書いて初期化をすることもできます.宣言後は(算術型であれば),代入により値が変わります.「a = b + c;」と書いたら,その時点の変数bとcの値を足し算して,結果を変数aに代入します(bとcの値は変わりません).「a = a + 1;」は,「変数aの値を1増やす」という意味になります…が「a++;」が同じ意味になるのでこちらを多用します.
 計算をするための算術演算子として,使いこなしたいのは,+と-と*と/,それと%です.足し算と引き算は,いいですね.掛け算は*で,割り算は/です.整数どうしの割り算で得られるのは商だけ(「5 / 2」は,2.5ではなく2)なのにも注意しましょう.「%」は,余り(剰余)です.「5 % 2」という式を評価すると,5÷2の余りということで1になります.剰余は,ツェラーの公式で曜日を求めたり,RSAをはじめとする暗号化の処理を行ったりするとき,重要な演算となります.
 中学・高校の数学で\{a-(b+c)\}dといった,複数のカッコを用いた式を書いてきたかもしれませんが,Cに限らずプログラミング言語ではカッコはそれぞれ異なる用途となるため,(a - (b + c)) * dと表すことになります.「( )の中に( )」など,同じ形状のものを中に入れた構造を,「入れ子」または「ネスト」といいます.
 代入の=と,比較のための<と<=と>と>=と,==と!=も,演算子です.日本語文字の「=」や「≧」などは,使用できません(コンパイル時にエラーとなります).代入はイコール1個なのに対し,等しいかどうかの比較はイコール2個です.「!=」は,俗に「びっくりイコール」ですが,「ノットイコール」と呼ぶといいでしょう.
 分岐や反復の制御文は以下が基本です.これらを組み合わせることで,変数の値に応じて,思うように処理をさせることができます.*3

/* if文 */
if (条件) {
  条件を満たすときの処理
}
/* if~else */
if (条件) {
  条件を満たすときの処理
} else {
  条件を満たさないときの処理
}
/* while文 */
while (条件) {
  処理
}
/* for文 */
for (初期化; 条件; 更新) {
  処理
}

 while文は,条件→処理→条件→処理→…の順に実行していき,条件を満たさなくなったところで終える(「}」の次に制御を移す)ことになります.for文はもう少し複雑で,初期化→条件→処理→更新→条件→処理→更新→…と実行します.while文もfor文も,最初の条件の判定結果が「偽」となった場合には,「処理」のところを一度も実行しません.
 はじめのプログラム例に含まれる「printf」は,ライブラリ関数の一つです.出来合いのものを使おうというわけです.printfは,決まった文字列のほか,算術型などの変数の値に応じた出力をしてくれます.printfの反対に,入力を行うライブラリ関数にscanfというのがあり,例えばint n;と変数宣言をしたあと,「scanf("%d", &n);」と書いて実行時に入力を獲得し,変数nに格納します.ライブラリ関数としてあと一つ,呼び出しの際に異なる,ランダム(でたらめ)な整数値を返してくれるrandという関数も,授業で取り上げました.「rand()」と呼び出して値を得ます*4.関数の定義や呼び出しにおいて,カッコの中に書く変数などを引数と言いますが,randは引数をとらない関数のため,カッコの次にすぐカッコ閉じを書きます.
 「配列」も授業で取り上げていますが本記事では割愛します.「さまざまな演算子」「文字と文字列*5」「ポインタ」「関数の再帰呼び出し」「構造体」「前処理指令」「ファイル入出力」「動的メモリ確保」を学習すれば,C言語をある程度,理解したといっていいでしょう.さまざまなプログラムを読み書きしながら技能を磨き,コードの良し悪しを判断できるようになるとともに,システムコールサードパーティライブラリを活用して,処理性能と読みやすさを両立させたプログラムを創っていきましょう!

*1:https://paiza.io/jaやなど,ブラウザ上でプログラムを実行できるサービスでは,コンパイル作業が陽に現れません.https://www.tutorialspoint.com/compile_c_online.phpではコンパイルと実行のコマンドが表示されますが,我々が打ち込むわけではありません.

*2:gcc hello.c」というコマンドを実行して,コンパイルをしたとき,「gcc」がコマンド名,「hello.c」がコマンドライン引数となります.

*3:「/*」から「*/」まで(複数行でもかまいません)や「//」から行の終わりまでは,コメントとなり,処理されません(コンパイル時に空白に置き換えられます).プログラムコードをコメントにすることを,「コメントアウト」といいます.

*4:「#include <stdio.h>」の次の行に「#include <stdlib.h>」を書くのも忘れずに.

*5:他のプログラミング言語と比べて,Cは文字列の連結(結合,足し算)が苦手です.例えばJavaScriptPythonなどなら"Hatena " + "Blog"という演算ができるのに対し,Cではこのように書くことができません.連結をするためのライブラリ関数はありますが,結果がどのように格納されるかについて,注意を払わないと,コンパイルは成功するけれども,あるときはSegmentation faultまたはBus errorといった実行時エラーでプログラムが終了し,またあるときは動作に問題がないように見えても,バッファオーバーランといったセキュリティ面での欠陥(セキュリティホール)を抱えるものとなってしまいます.