最終更新:2014/6/3
今回の内容は概念を理解するというよりは使い方を覚えるというのが主眼になっています。
ですので演習課題以外にも自分でたくさんプログラムを書いて使えるようにしてください。
指定されていない他のAOJの問題を解くのも有効だと思います。
プログラムは常に一本道で動くとは限りません。
例えば数の入力を受け取って100より大きかったらA、小さかったらBというようにしたい場合、
入力された値から判断して処理を分岐させなくてはなりません。
そこでif文というものを使います。具体的には以下のようにします。
if(条件式) 条件式が真だった時に実行する文;
なおこれでは1つの文しか実行できません。
しかし{ }で囲むことで複数の文をif文の分岐で実行することが出来ます。
if(条件式){
条件式が真だったらする処理
}
同様に条件式が成り立たなかった時の処理もelseを使って表現できます。
if(条件式){
条件式が真だったらする処理
}else{
条件式が偽だったらする処理
}
これを組み合わせてもっと複雑な条件分岐を作ることができます。
if(条件A){
Aだった場合の処理
}else if(条件B){
Bだった場合の処理
}else if(条件C){
if(条件D){
CかつDだった場合の処理
}else if(条件E){
CかつEだった場合の処理
}
}else{
A~Cのどれでもなかった場合の処理
}
では条件式について学んでいきましょう。
まず最初にC言語における真と偽というものを知らなくてはなりません。
簡単な定義ですがとてもとても重要です。
C言語において
真(true)とは0以外の値
であり
偽(false)とは0
です。
数学の等式、不等式に使われる記号と同じものがあります。
演算子 | 数学における記号 | 使用例 |
== | = | a == b |
!= | ≠ | a != b |
< | < | a < b |
<= | ≦ | a <= b |
> | > | a > b |
>= | ≧ | a >= b |
注意して欲しいのは数学のように 0<x<100 のような書き方が出来ない点です。
そういった式は次の論理演算子を用いて表現します。
こちらも数学で使うものと同様のものが用意されています。
演算子 | 数学における記号 | 使用例 | 備考 |
&& | ∧ (AND) | 0<x&&x<100 | |
|| | ∨ (OR) | a!=0||b!=0 | |
! | ¬ (NOT) | !(a==0&&b==0) | 真偽の値を反転させます。 |
100回"Hello World"と表示するプログラムを作成せよ、と言われてprintfを100回各必要はありません。そういった時のために繰り返しを行える構文があります。
英語のwhileの意味のとおり「~の間」だけ処理を繰り返します。具体的には、
while(条件式A){
条件式が真の間繰り返す処理B
}
こういった繰り返し処理のことをループと読んだりします。
処理の流れとしては
注意点としては条件式Aが常に真のままだといつまでたってもループから抜け出せない(無限ループ)に陥ることがあります。
while文と似たようなものでdo-while文というものがあります。
while文が条件式の値が偽の場合、一度もループ内の処理が行われないのに対してdo-while文は最低でも一度はループ内の処理が行われます。
具体的には以下のように書きます。
do{
ループで行う処理B
}while(条件式A)
最初に処理Bを行った後に条件式Aの真偽を調べて真なら再度Bを繰り返します。
主に決まった回数繰り返したいときに使われます。
for(開始処理A;繰り返し条件B;継続処理C){
繰り返したい処理D
}
具体的な処理の順番は
例えば以下のコードは
int i;
for(i=0;i<10;i++){
printf("%d\n",i);
}
このような出力をします。
0
1
2
: //省略
7
8
9
注意して欲しいのは変数iは0から9までを移動している点です。
何かエラーが起きた等でループ処理の途中でループから抜け出したい時break文が便利です。
break文は実行されると今いる一番小さいループから抜け出します。具体的には
while(条件式1){
処理
:
if(条件式2){//例えばエラーが起きたかどうか調べる条件式
break;
}
:
処理
}
ループの外
この場合条件式2が真になるとbreak文が実行されif文よりも後ろの処理を飛ばしてループの外の処理に移行します。
break文と似ていますがbreak文がループを抜けて次の処理に移るのに対してcontinue文はループの最初に戻ります。
またfor文の中でcontinueを使うと継続処理を行った後ループの最初に戻ります。
2つか3つに分岐するプログラムならif-else文でも書けますが5つや6つ、もしくはそれ以上に分岐する場合if-else文で書こうとすると大変なことになります。
switch文を使うとそういった分岐を簡潔に記述することが出来ます。
switch(値X){
case A:X==Aなら行う処理;break;
case B:X==Bなら行う処理;break;
case C:X==Cなら行う処理;break;
case D:X==Dなら行う処理;break;
:
default:どれでもなかったら行う処理;
}
なおX,A,B,C,D・・・は全て整数の値しか取れません。
最後のbreakを書かないとそれより下のcase全て実行されてしまいます。
今まで変数はmain関数の最初でしか宣言してきませんでしたがforやwhileのループの 中でも宣言することが出来ます。
while(hoge){
int a,b,c;
a=10;
b=20;
c=a+b;
}
ただこのループの中で宣言された変数はこのループの中でしか使えません。
こういった変数の有効範囲のことをスコープと言います。
またスコープの中と外で同じ名前の変数が混在している場合、
よりスコープの狭いほうの変数が優先されます。
例えば以下のコードを実行してみると
//scopetest.c
#include<stdio.h>
int main(){
int a=10;
int i;
for(i=0;i<1;i++){
int a=20;
printf("forの中のa%d\n",a);
}
printf("forの外のa%d\n",a);
}
以下のようになります。
[hoge@sol ]$ gcc scopetest.c -o scopetest
[hoge@sol ]$ ./scopetest
forの中のa20
forの外のa10
forの中ではforの中で宣言されたaが優先されていることがわかるかと思います。
main関数の外に変数を宣言した場合その変数はプログラム中のどこからでも呼び出すことができます。
#include<stdio.h>
int global;
int main(){
global=100;
}
一見便利なようですがプログラムのどこからでも変更できるというのは大きなプログラムを作成する際に安全でないことのほうが多いのでなるべく使わないようにしましょう。
演習 1: 数値の入力を一つ受け取ってそれが100以上ならば”high”,100未満ならば"low"と出力するプログラムを作成せよ
演習 2: AOJ10003 Small, Large, or Equal
演習 3: AOJ10004 Sorting Three Numbersメンドイ
演習 4: AOJ10005 Print Many Hello World
演習 5: AOJ10006 Print Test Cases
演習 6: AOJ10007 Swapping Two Numbers
演習 7: AOJ 0000 QQ
演習 8: AOJ10010 Simple Calculator発展的な内容
この 作品 は クリエイティブ・コモンズ 表示 - 非営利 - 改変禁止 2.1 日本 ライセンスの下に提供されています。免責事項