[ quoted from ] 情報演習 課題C-A-1(※)一部抜粋・改変

2×2正方行列A=[[a,b],[c,d]]の、a,b,c,dの値をキーボードから入力し、以下のような出力を計算して表示させよ。ただし、a,b,c,dの値はdouble型の浮動小数点とする。

逆行列A^-1が存在しないとき
逆行列が存在しない旨を画面に表示する。
逆行列A^-1が存在するとき
以下の3つの計算結果を表示する。
  1. 逆行列A^-1
  2. 逆行列との積A^-1の計算結果
  3. 逆行列との積AA^-1の計算結果

C言語の課題はSchemeの課題に比べ、より実践的な内容になっています。例えば、行列積分計算などが題材にされています。このようなプログラミングでの計算は、物理系(特に実験系)に進む人にとって間違いなく必要になるでしょう。

実践的なプログラミングで重要になるのは、いかにして自分の作ったプログラムのデバッグ(バグを取り除くこと)をするかです。そのためには、情報演習ページで見れるCプログラミング資料(PDF)や、Web上にある適当なCリファレンスなどを参照しながら、何が正しい文法で、どこが間違っているのかを常に意識する必要があります。

この課題のプログラムそのものは非常に易しく、明らかに基本事項を練習するための課題です。そこでこのページでは、課題C-A-1に関連する重要な文法間違えやすい個所に特化してまとめました。課題C-A-1のプログラムに取り組む過程でありがちなミスに重点を置いた文法解説なので、上手くデバッグに役立ててください。

実際、プログラマの仕事はデバッグであるとよく言われます。プログラマーと言うと高速でプログラムをタイプして華麗にコンピュータを操っているようなイメージがあるかもしれませんが、実はやっていることの大半はデバッグだけです。寧ろ、最初に作ったプログラムで何もエラーが出なかった方が怖いと思って下さい。エラーが出たからと言って慌てふためかずに、幸せなことに自分のプログラムは間違っていたんだ、ぐらいに考えましょう。

以下にC言語プログラムの基本形を示しておきます。微妙なミスでもコンパイルエラーが出ることがあるし、細かい意味を覚える必要もないので、コピペ推奨。

// 標準入出力に必要
#include <stdio.h>

int main(void){
  // メインの処理はここに記述する。
  return 0; //正常終了
}

//で始まる行と、/*と*/で挟まれた部分はコメントになります。自分のプログラムが分からなくなるといけないので、ちゃんと書きましょう

C言語では変数にいくつも型があり、最初は覚えるのが面倒です。しかし実際のところ、C言語の課題で必要になるのは、整数のint型と、倍精度実数のdouble型ぐらいです。一応このページでは他の基本的な型である単精度実数のfloat型と文字のchar型まで含めて解説していますが、intdouble以外は飛ばして読んでもオッケーです。

ちなみに、応用課題C-X-1では文字列処理が必要になるので、char型とchar型配列についても説明しています。まぁ、普通は発展課題までで十分でしょう。

変数宣言の書式
宣言例 注釈
整数型 int num=0; num, n, m, l, i, j, k などが変数名としてよく使われる
単精度実数型 float x=0.0; 精度が悪いのであまり使わない。
初期化式の0.0という書き方は実数であることを明示。
倍精度実数型 double a=0.0; なんか変数を作ったらまずこれだと思おう。
a,b,x,y,theta,dx,deltaと数学っぽいもの大体これね。
文字型 char s=`s`; str,sなどがよく使われる。1文字分しか入らないことに注意。
文字列(文字配列) char str[N]="hoge"; 文字が(N-1)文字入る。

なお、変数宣言のイコールほにゃららの部分を初期化式と言います。これは省略することもできますが、初期化しない変数を使ってプログラムを組むと予期しない動きをする可能性があります。自分で必要な時に初期値を代入してもいいのですが、それを忘れた場合にやばいので、慣れないうちは必ず適当な値で初期化する癖をつけましょう。

よく使う記号に、算術演算子(四則計算など)や、比較演算子(不等号)があります。これもまれに間違えるので注意が必要です。基本的に同じ型の値同士で計算・比較するべきです。

算術演算子
記号 説明
+ ぷらす。
- まいなす。
* かける。欧米では×なんて使わない。
/ わる。欧米では÷な(略)
% あまり。100%==1ではない。
比較演算子
記号 説明
== 両辺が等しいなら真。1個だけのイコール=はNG
!= 両辺が等しくないなら真。
< 左辺が右辺未満なら真。
> 左辺が右辺より大なら真。
<= 左辺が右辺以下なら真。=<ではない
>= 左辺が右辺以上なら真。=>ではない

その他の注意点

  • 全角記号が使える訳がない。
  • 0で割れる訳がない。
  • 7/41になる(整数除算の結果は整数)。
  • 7.0/47/4.07.0/4.01.75になる。
  • 剰余演算子%は整数にしか使えない。

一般的にキーボードからの入力を得るにはscanf関数を使います。大体の場合には、変数名の頭にアンパサンド&をつける必要があります。細かい理由はいいので暗記。

scanf関数の書式
変数 フォーマット指定子 ポインタ 用例 注釈
int num; %d &num int num;
scanf("%d",&num);
整数。
float x; %f &x float x;
scanf("%f",&x);
単精度実数。
double a; %lf &a double a;
scanf("%lf",&a);
倍精度実数。指定子に注意。
char s; %c &s char s;
scanf("%c",&s);
文字(1文字)。
char str[N]; %s str char str[N];
scanf("%s",str);
文字列(複数文字)。&は不要。

実はscanf関数は使い方を間違えると危険な関数です。しかし、正式なプログラムを書くわけではないし、課題や自分で使うプログラムを書く分にはscanfで十分です。実際、このレベルの課題でそこまで求められてはいません。

プログラムの結果を出力するにはprintf関数を使います。一部の指定子がscanf関数と微妙に異なることに注意してください。

printf関数の書式
フォーマット指定子 用例 注釈
整数 %d/%i printf("整数 : %d",1); int型。%dと%iのどちらでも同じ。
小数 %f printf("小数 : %f",3.14); float/double型。double型はscanfとの違いに注意
文字 %c printf("1文字 : %c",'s'); char(1文字)。
文字列 %s printf("複数文字 : %s","test"); char型配列(複数文字)。