
No.7ベストアンサー
- 回答日時:
テストで白紙から記述するとなると、間違うこともあるかもしれません。
通常、for文とif文はどこにでもあるありふれた構文なので、ソーステキストの近所からコピーしてすこし修正すればすぐできるし、構文誤りは、エディターが指摘してくれるので、実務的には、いい加減にやっても、完成するんですが。
しっかり覚えておくことですね。カッコ()と{}と;をとくにしっかり。
No.6
- 回答日時:
ねんのためかってにほそく.
++ は, その文脈では単純に「1 増やす」と思えばいい. つまり
i++
とあったら「i の値を 1 増やす」ってことだ.
注意: 1つの式で同じ変数 (上の場合は i) を 2度以上使うとおかしなことになるかもしれない.
No.5
- 回答日時:
さて、条件分岐を終えれば次は繰り返しのforだ。
その前に。
次のようなC言語によるプログラムを見てみる。
/* 例1: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int j = 5;
if (j < 10) {
goto FOO;
}
puts("この文は印字されない");
FOO:
return EXIT_SUCCESS;
}
これもコンパイルして実行してみれば分かると思うんだけど、「何も表示されずに」すぐさま終了してしまうプログラムだ。
if節に含まれてるgotoと言うのがジャンプ命令で、条件節が真の場合、即刻定義されたラベル(このケースだとFOO)に飛んでそのままプログラムを終わらせてしまう。
この場合はラベルFOOはif文の後ろにあるわけだけど、実は前にあっても良い。こんな事が出来る。
/* 例2: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int j = 0;
FOO:
if (j < 10) {
printf("%d回目!\n", j + 1);
j++;
goto FOO;
}
return EXIT_SUCCESS;
}
if節内のgoto FOOが実行される毎にラベルFOOに飛び、またFOOの下から実行される。
jの値は1づつ増えてるんで、j < 10と言う条件を満たしてる間はバカみたいに同じ事を実行する(コンパイル/実行して確かめてみること)。
そして気づくでしょ?確かに「繰り返し」してんだ、と。
と言うわけで、ジャンプ構文と条件分岐さえあれば繰り返しを書く事は可能です・・・がメンド臭くね?
プログラミングに於いては「メンド臭い」は悪。従って、上で書いたような「条件分岐とgotoを用いた」結果をもっと簡単に記述出来ないのか、ってぇんで出来たモノの一つがfor文なわけ。
forは次のようにして使う。
for (初期化;条件式;変化式) {
実行する処理(複数可);
}
これを使うと上の例2は次のように書き換えられる。
/* 例3 */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
for (int j = 0; j < 10; j++) {
printf("%d回目!\n", j + 1);
}
return EXIT_SUCCESS;
}
分かる?「同じ結果になるのに」圧倒的に短くなってるでしょ?
前も書いたけど、繰り返し構文ってのは理論的に言うと「必要がない」の。
ないけどあるのは何故か、と言うと「圧倒的に書く量が減る」から。
それが基本的な旨味なのよ。同じ事やるなら短く書けた方がエエんちゃいまっか?って事だな。
いずれにせよ、例2と例3を良く見比べてみること。例2のどの部分が例3で「コンパクトに書かれてるのか」キチンと押さえておこう。
で、ここで見た通り、forは条件分岐のifなんかより抽象度が高い機構なんで、「習うより慣れろ」度は条件分岐より高いんだ。特定のパターンで「ハマる」とか言う事は正直条件分岐より無い、って言って良い・・・大体、構文的な問題じゃなくって、単なるケアレスミスで、例えば無限ループに陥る、とかセグフォする、とかになるだけ。それはそれで頻出だけどな(笑)。
例えば良くある初心者向けのforの使い方の例示、ってので「掛け算での特定の段を表示させろ」ってのがある。以下は12の段の場合。
/* 例4 */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
for (int i = 1; i < 13; i++) {
printf("%d x 12 = %d\n", i, i * 12);
}
return EXIT_SUCCESS;
}
コンパイルして実行すれば分かるだろうけど、掛け算で1×12〜12×12まで全部表示する。
これは基礎的なforの使い方さえ分かればすぐ分かるでしょ。
さて、C言語は他のモダンな言語のように「配列」をそのまま表示する機能が無いショボい言語だ。
だから配列相手にルーピングして、一々配列要素を表示しなきゃならない、って事が良くある。
例えば次のようなパターンが良く使われる。
/* 例5 */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int array[] = {1, 2, 3};
for (size_t i = 0; i < sizeof(array)/sizeof(array[0]); i++) {
printf("%d\n", array[i]);
}
return EXIT_SUCCESS;
}
こんなカンジで、とにかく配列が現れるとまず印字絡みではforのお世話になる。
ホント頻出なんで良く覚えておこう。
あと、初心者が混乱するのは、for文のネストだ。
「配列の配列」を印字したりする場合にも使われるんだけど、初心者用のお題として良くあるのは、掛け算の九九表みたいなヤツを作れ、ってヤツかな。
落ち着けば解けるんだけど、大体初心者は落ち着きがない(苦笑)。
例えば次のようなコードは頻出パターンだ。
/* 例6*/
#include <stdio.h>
#include <stdlib.h>
int main(void) {
for (int multiplier = 2; multiplier < 13; multiplier++) {
for (int j = 1; j < 13; j++) {
printf("%d x %d = %d\n", j, multiplier, j * multiplier);
}
puts("-------------- \n");
}
return EXIT_SUCCESS;
}
例えばここではputs文は外側のforに属してて内側のforには属してない。
「どのfor」が「どの命令」を実行するように設計するのか、ってのが初心者には見えないケースが多いんだな。
もっとも、教授側もあまり丁寧に説明せず、「フツーのforが出来れば入れ子もO.K.だろ」って簡単に考えてるケースが多いように思う。
上の例を良く精査して勉強して欲しい。
あとはやっぱり練習問題をガンガン解くしか無いんじゃないでしょうか。
練習問題は、例えば以下のページにあります。
5. 繰り返し処理:
http://kitako.tokyo/lib/CExercise.aspx?id=5
なお、if + for文の総仕上げとしては。
有名なFizzBuzz問題を解いてみる事。
FizzBuzz問題:
1から100までの数字を画面に表示する。ただし、3の倍数のときは数字の代わりにFizzと表示し、5の倍数のときは数字の代わりにBuzzと表示し、15の倍数のときは数字の代わりにFizzBuzzと表示する
これが解ければ初級者用のC言語のifとforを使ったテスト、なんかは簡単にクリア出来るたぁ思うんだけどね。
最後に力試しとして上のFizzBuzz問題に挑戦してみて下さい。
No.4
- 回答日時:
>C言語でfor文とif文を簡単に1からかける方法ないですか?
C言語でfor文とif文を使って書いたプログラムを読んで理解すること
でしょうかね。
例:1から100までの数で2あるいは9の倍数を出力するプログラム
for(i=1; i<=100; i++) {
if(i%2==0 || i%9==0) printf("%d ",i);
}
みたいな感じかしら
No.3
- 回答日時:
> 練習問題もプリントすら配られてないです。
あ、そう。
ふーん。
練習問題があればある程度の出題予想も付くんだけどねぇ・・・・・・。
実際、このテのヤツって練習問題を解きまくるしかないんですよ。
計算練習と同じ。
Cのif文は構文的には
if (条件式1) {
計算1(複数ある場合がある)
} else if (条件式2) {
計算2 (複数ある場合がある)
} ....
....
....
} else {
計算n(複数ある場合がある)
}
ってこれだけ、なんだよな。
実の事言うと構文自体は大して難しくない。
問題は条件式の部分で、良くあるミス(プロでもたまにやる)ってのは
・等値を判定するつもり(==を書かないとならない)だったのを間違えて代入記号(=)を書いちまった
ってのが「あるある」です。
つまり、初心者が引っかかるのはこの「あるある」をやっちゃうとか、あるいは比較する際にC言語だと「比較する値同士」の型が違ってた、とかなんだよね。
でもこの辺りのミスは「皆通る道」です。
/* 例1: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
if (12 > 10) {
puts("12は10よりも大きい");
}
return EXIT_SUCCESS;
}
これは必ず出力関数putsが実行されるパターン。12は10より大きくて必ず真になるからif文の中身は必ず実行される。
逆の例は次のようなカンジ。
/* 例2: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int j = 5; /* jを整数として宣言して5を代入する */
if (j > 10) { /* 比較対象(10)も整数型である事を確認しよう */
puts("この文字列は表示されない"); /* 条件節は偽なんでif節の中身はスキップされる */
} else {
return EXIT_SUCCESS; /* 結果ここしか実行されない */
}
}
/* 例3: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int j = 5;
if (j <= 10) { /* "より大きい"を"以下"にして論理を反転 */
return EXIT_SUCCESS;
} else {
puts("この文字列は表示されない");
}
return EXIT_SUCCESS; /* ここは実は実行されない(if節内部で終了するから) */
}
このパターンだと「何も表示されずに」プログラムはすぐ終了します。
実際、コンパイルして実行して確かめて下さい。
さて、数値の比較は(整数であれ浮動小数点数であれ)簡単なんだけど。
気になるのは、
> ダブルコーテーションなど細かいところも見るらしい
と言う記述。
う〜ん、文字列の比較もアリなんか?
C言語だと文字列の正体は文字型の配列で、これは当然数値ではないので、等値比較する際には==が使えない。
従って、string.hと言うヘッダに含まれてるstrcmpを使わないとならない。
これがさっき書いてた事で、「条件分岐構文自体」は簡単なんだけど、難しいのはそっちじゃなくって、「適する条件式を書く」事なんだ。
/* 例4: */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char color[] = "赤";
int score = 20;
int bonus = 0;
if (strcmp(color, "赤") == 0) { /* 文字列同士の比較 */
bonus = 0;
} else {
if (strcmp(color, "青") == 0) { /* 文字列同士の比較 */
bonus = score * 2;
} else {
if (strcmp(color, "緑") == 0) { /* 文字列同士の比較 */
bonus = score / 2;
} else {
puts("未登録のカラーです");
}
}
}
printf("カラー: %s, 得点: %d, 配当: %d\n", color, score, bonus);
return EXIT_SUCCESS;
}
「適する比較演算子、ないしは比較用関数(述語と呼んだりする)」をキチンと選ぶ事を学べば難しくないんだけど、そうじゃなかったら混乱する例でしょう。
なお、例の4番はif〜elseの入れ子(ネスト、等とも呼ぶ)になってるんだけど、フツープログラマとかはこういうネストを嫌う事が多い。
「コードの見た目」がもうちょっとフラットに見える方を大方の人々は好む。
そういう場合は、if〜elseをネストせずにif〜else if〜... elseを使う。
例4をもうちょっとマシに書き換えると次のようになる。
/* 例5: */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char color[] = "赤";
int score = 20;
int bonus = 0;
if (strcmp(color, "赤") == 0) {
bonus = 0;
} else if (strcmp(color, "青") == 0){
bonus = score * 2;
} else if (strcmp(color, "緑") == 0) {
bonus = score / 2;
} else {
puts("未登録のカラーです");
}
printf("カラー: %s, 得点: %d, 配当: %d\n", color, score, bonus);
return EXIT_SUCCESS;
}
こうすれば見た目が例4よかマシになる。
意外と思うかもしれないけど、プログラミング言語では「本質的には必要がない」機能でも、このように「見た目が良くなるから」採用する構文の形式がある、って事。
書くのがメンド臭かったり読むのが面倒くさくなるよりはマシだろ、って事だよね。
あと、if文の落とし穴としてはこういうのがあります。
/* 例6 */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int value = 100;
if (value > 10) {
puts("これは問題ない。");
} else if (value > 50) {
puts("この文字列は\"決して\"表示されない");
} else {
puts("これも表示されない");
}
return EXIT_SUCCESS;
}
これは最初の条件節が真になった時、かならずelse if節もelse節も真である、ってトコが「間違い」の部分。
文法的には正しくてもロジックがミスってる、って場合もあるのね。
要するに最初の条件節が偽になる場合、全部の条件節が偽になっちゃうように書くのはマズい(ある値が10以下ならそれは50以下になるのは当たり前だし)。つまり、「条件節を置く順番を」キチンと考えないとならない、って事がしばしば起こるわけだ。
あとは例えばこういうパターンを覚えておく。
/* 例7: */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int x = 15;
if (x < 10) {
puts("xの値が有効範囲内にありません");
} else if (x > 20) {
puts("xの値が有効範囲内にありません");
} else {
printf("x = %d\n", x);
}
return EXIT_SUCCESS;
}
最初のif節と次のelse if節の処理内容が全く同じだ。
こういう場合は論理演算子を使うんだけど、C言語の場合は括弧が多くなるんで紛らわしくなるけど、これも慣れるしかない。
/* 例8 */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int x = 15;
if ((x < 10) || (x > 20)) {
puts("xの値が有効範囲内にありません");
} else {
printf("x = %d\n", x);
}
return EXIT_SUCCESS;
}
あとは練習問題でもやってみて。
4. 分岐処理
http://kitako.tokyo/lib/CExercise.aspx?id=4
いずれにせよ、「構文」じゃなくって「適した条件式の書き方」の方が重要だ、と言う話です。
No.2
- 回答日時:
> 明後日if文とfor文が混ざったテストが出るんですけどほんとに理解出来なくてどう考えたら1からかけるようになるのかなって感じです
あ、そう。
ふ~む。
ちなみに、より本質的なのはifの方なのね。
実の事言うと、理論的な話をすれば、for文みたいな繰り返し構文ってのはあっても無くても良いです。
本当にアセンブリ言語でのジャンプ構文を抽象化してるのはifなんかの条件分岐の方。forとかwhileのような「繰り返し構文」ってのは条件分岐の上に組み立ててる「より高度に抽象化された」機能なの。
あくまで理論的には、って話なんだけど。
なんか練習問題とか無いのかしらん。
あったら説明出来るかもしんない。
この回答へのお礼
お礼日時:2022/03/02 17:06
練習問題もプリントすら配られてないです。
ダブルコーテーションなど細かいところも見るらしいので赤点回避出来たら良いなって感じです
No.1
- 回答日時:
> C言語でfor文とif文を簡単に1からかける方法ないですか?
ちょっと言ってる意味が分からん(笑)。
そもそも、for文とif文ってのはアセンブリでのジャンプ構文にあたるものを「簡単に1から書ける方法」として開発されたもので、そこそこ(そのレベルでは)簡単に1から書ける方法になっています。
が。
さらなる抽象化、っつーのはC言語のレベルでは実装されてません。
どー言った意味で言ってるんだろ。
単に貴方がfor文とif文が苦手です、って話なのかしらん?
この回答へのお礼
お礼日時:2022/03/02 16:55
明後日if文とfor文が混ざったテストが出るんですけどほんとに理解出来なくてどう考えたら1からかけるようになるのかなって感じです
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
入力した数値を倍々するプログラム
-
break文でループを一気に抜ける...
-
do-while文が禁止される理由
-
エクセルVBAで Do While (1)って?
-
放電現象の2分法C言語プログラ...
-
繰り返し文の利点について
-
無限ループ対策
-
Matlabを使った心理学実験
-
C言語、whileループを抜け出す...
-
C言語のwhile()文での大括弧の...
-
for文while文の無限ループの違...
-
ループを途中で抜けたいのですが。
-
エクセルでC言語のfor文と同じ...
-
__asm int 3でのブレイクポイン...
-
strtokを使用したループ内でのs...
-
if文の中にfor文なのか、for文...
-
C言語について。
-
C言語について
-
信頼区間の1.96や1.65ってどこ...
-
2÷3などの余りについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
break文でループを一気に抜ける...
-
入力した文字列から母音だけを...
-
do-while文が禁止される理由
-
ループを途中で抜けたいのですが。
-
エクセルでC言語のfor文と同じ...
-
if文の中にfor文なのか、for文...
-
For文の終了値を関数にしても問...
-
入力した数値を倍々するプログラム
-
Excel VBAで年度をまたぐ期間の...
-
エクセルVBAで Do While (1)って?
-
C言語forループが完結した場合...
-
Cプログラムが終了しない
-
for文while文の無限ループの違...
-
放電現象の2分法C言語プログラ...
-
UWSCにてある一定の動作を無限...
-
繰り返し文の利点について
-
アルゴリズムです!四つの数字...
-
プログラムで関数は使わない方...
-
PAD図の書き方
-
PIC のプログラムについて ど...
おすすめ情報
簡単なやり方あれば教えて欲しいです