プログラミング成長日記 #4 -奔走-
こんにちは!トマトです🍅
今日もまたC言語やっていきます!
今回から少しずつつまる部分も出てくると思うので、その試行錯誤の過程を見ていただけたらと思います。
ではいきましょう!
-このシリーズはこの本を見ながら進めています
https://www.amazon.co.jp/dp/479737702X?tag=note0e2a-22&linkCode=ogi&th=1&psc=1
・do文
do{
} while ();
do文はwhileの括弧の中が正しい間{}の中を繰り返し続けるというものらしく、かなり使われてそうな便利なものに見えるな。
while文の中に続けますか?で入力させた数字の判別を行うことで一気にそれっぽいものができる。笑
実際に書いてみます。演習4-2をやってみます。
#include <stdio.h>
int main (void){
int a, b, sum, min, max, start;
printf("整数を入力してください\n");
printf("整数a:");
scanf("%d", &a);
printf("整数b:");
scanf("%d", &b);
if(a > b){
min = b;
max = a;
sum = b;
start = b;
}
else{
min = a;
max = b;
sum = a;
start = a;
}
do{
start++;
sum += start;
} while (start < max);
printf("%dから%dまでの数の和は%dです。", min, max, sum);
}
入力された2数自身とその数の間の数を足して表示するというもの。
結果は
整数を入力してください
整数a:12
整数b:16
12から16までの数の和は70です。%
最後の改行忘れたけどできてる。
でも同じ数を入れると...
整数を入力してください
整数a:12
整数b:12
12から12までの数の和は25です。%
やっぱそうなるよな。これどうすればいいんだ?
てかこれただのwhile文でdo文の意味が全くない笑
この足して結果を表示すること自体をdo文で何回もできるようにするんかな?笑
まあ使い方は分かったから次に進みましょうか笑
・while文
と思ったらwhile文はまだでてきてませんでした笑
じゃあさっきのはあってたんかな?
ここへのつなぎだったことを信じることにします笑
同じ数入れた時の不具合はdo文の最初にifで最初はなにも足し算しないみたいなのを作って最初にwhile文の中身を判定させればいけるでしょう!もっと綺麗なやり方絶対あるけど知らん!!
さて、次はwhile文です。
whileの横のカッコの中が正しいうちは{}の中を繰り返すという感じでdo文とほぼ変わらん感じです。
while文も書いたことあるので演習問題一つやって次行きましょう。
4-10です。
int main (void){
int num;
printf("正の整数:");
scanf("%d", &num);
while(0 < num){
putchar('*');
num--;
}
printf("\n");
}
結果
正の整数:6
******
最初while文のかっこわすれてて一行だけwhile文の中に含まれてしまい無限に*が出てきて超焦りましたがなんとかできました。
あと、補足説明として、i++について解説されていました。i++自体を比較することができるらしく、i++はiとして比較計算をした後にiに1をたすらしいです。++iはその逆で、足し算をした後に比較などが行われるので、使い分けをすることが大事みたい。
まあ慣れるまでは別々に書きますよ。笑
じゃあ次行きましょう!
・for文
次はfor文。
今のところ自分が描くコードでは一番出場する機会が多いこの文の自分の理解を話しておくと、
for(int i = 0; i < n; i++){
}
これでiを0に設定して、
2個目の不等号が満たされてる時は{}の中を実行して、
その後に一番右に書いてあることを実行する。
っていうのを二番目の式が真である間やり続けてくれるやつです。多分。
だから
#include <stdio.h>
int main (void){
for(int i = 0; i < 0; i++){
printf("hello\n");
}
}
ってやっても何も表示されないのよね。
一番最初に式の判定をしてくれるから、さっきみたいに無理矢理最初はカッコ内の手順を飛ばすみたいなことを書く必要がなくてとても便利。
これも慣れているほうではあるので、演習問題一つやって次行きましょう。
4-19です。
#include <stdio.h>
int main (void){
int num, count = 0;
printf("正の整数:");
scanf("%d", &num);
for(int i = 1; i <= num; i++){
if(num % i == 0){
printf("%d\n", i);
count++;
}
}
printf("%dの約数は%d個です\n", num, count);
}
結果
正の整数:352654367
1
13
491
6383
55249
718237
27127259
352654367
352654367の約数は8個です
約数をしらみ潰しに探していって個数も表示するやつです。今時のコンピューターってマジで計算早いんだなこの量のfor文ぶん回したくせに結果秒で出たぞ。
マジで文明の利器。
では次行きますか。
・多重ループ
多重ループは、for文の中にfor文を入れることで、表とかを作るのに使えるのかな?って感じのやつですよね。
ここでも演習問題を一つ。4-20です。
#include <stdio.h>
int main (void){
printf(" | ");
for(int i = 1; i < 10; i++){
printf(" %d ", i);
}
printf("\n");
for(int i = 0; i < 32; i++){
if(i == 3){
printf("+");
}
else{
printf("-");
}
}
printf("\n");
for(int i = 1; i < 10; i++){
printf(" %d | ", i);
for(int j = 1; j < 10; j++){
printf("%3d", i * j);
}
printf("\n");
}
}
結果
なんかとっても辻褄合わせ酷くて大変なコードになってるけどまあいっか。
こんなことに使えるんだな。
次!!
と思ったら4章が終わりました。まだまだいきましょう!!!
・配列
配列は、型が同じ情報をひとまとまりにできるって感じかな?
これはとてもたくさん使いそうな予感がしますがどうでしょうか。
これは授業でやったんですが、aという配列がある時に、これはaというのはポインタ?で、a[1]などと書くと、a + 1 に入っている値が表示されるだけなので、1[a]と入力しても、1 + aになるだけなので正しく表示されるらしい。
ということを聞いたのでやってみます。
結果
#include <stdio.h>
int main (void){
int a[] = {1,2};
printf("%d\n", a[1]);
printf("%d\n", 1[a]);
}
2
2
ほんとにできた。面白いな。
でも一つ疑問なのが、ポインタ?の場合はa + 1 * (intが必要なビット数)みたいな感じで1に何かしらかけられているはずなんだけど、それが逆転しちゃうとダメってならないのかな?
ということで他の型でもできるのかやってみました。
#include <stdio.h>
int main (void){
char a[] = "qw";
printf("%c\n", a[1]);
printf("%c\n", 1[a]);
}
w
w
うーん。できるな。
intのずらす数がたまたま一つ分で、a + 1 * 1みたいになっていてかつ、intとcharの使うビット数かなんかが一緒で同一の計算がされている可能性しか自分には考えられませんが、どういうことなんでしょうか。
まあこれはいつかわかることでしょう。笑
ということでこれもさくっと演習やって次へ。
5-9です。
#include <stdio.h>
#define MAX 80
int main (void){
int number, max = 0, ele;
int range[11] = {0};
printf("人数を入力してください:");
do {scanf("%d", &number);
if(1 > number || MAX < number){
printf("1以上%d以下で入力してください:", MAX);
}
} while(1 > number || MAX < number);
printf("%d人の点数を入力してください\n", number);
for (int i = 0; i < number; i++){
do{
printf("%d番:", i + 1);
scanf("%d", &ele);
if(ele < 0 || ele > 100){
printf("0以上100以下の数を入力してください");
}
} while(ele < 0 || ele > 100);
range[ele / 10]++;
}
printf("---分布グラフ---\n\n");
for(int i = 0; i < 11; i++){
if(max < range[i]){
max = range[i];
}
}
for(int i = max; i > 0; i--){
for(int j = 0; j < 10; j++){
if(i == range[j]){
printf(" *");
range[j]--;
}
else{
printf(" ");
}
}
if(range[10] == max){
printf(" *");
range[10]--;
}
printf("\n");
}
for (int i = 0; i < 34; i++){
putchar('-');
}
printf("\n");
for(int i = 0; i < 11; i++){
printf(" %d", i * 10);
}
printf("\n");
}
結果
人数を入力してください:20
20人の点数を入力してください
1番:12
2番:23
3番:34
4番:45
5番:56
6番:67
7番:78
8番:89
9番:90
10番:100
11番:32
12番:85
13番:73
14番:65
15番:82
16番:81
17番:64
18番:85
19番:52
20番:34
---分布グラフ---
*
*
* * *
* * * * *
* * * * * * * * *
----------------------------------
0 10 20 30 40 50 60 70 80 90 100
と思ったら違うし。
100の表示のところがmaxと比較しちゃってるので直してきます。笑
#include <stdio.h>
#define MAX 80
int main (void){
int number, max = 0, ele;
int range[11] = {0};
printf("人数を入力してください:");
do {scanf("%d", &number);
if(1 > number || MAX < number){
printf("1以上%d以下で入力してください:", MAX);
}
} while(1 > number || MAX < number);
printf("%d人の点数を入力してください\n", number);
for (int i = 0; i < number; i++){
do{
printf("%d番:", i + 1);
scanf("%d", &ele);
if(ele < 0 || ele > 100){
printf("0以上100以下の数を入力してください");
}
} while(ele < 0 || ele > 100);
range[ele / 10]++;
}
printf("---分布グラフ---\n\n");
for(int i = 0; i < 11; i++){
if(max < range[i]){
max = range[i];
}
}
for(int i = max; i > 0; i--){
for(int j = 0; j < 10; j++){
if(i == range[j]){
printf(" *");
range[j]--;
}
else{
printf(" ");
}
}
if(range[10] == i){
printf(" *");
range[10]--;
}
printf("\n");
}
for (int i = 0; i < 34; i++){
putchar('-');
}
printf("\n");
for(int i = 0; i < 11; i++){
printf(" %d", i * 10);
}
printf("\n");
}
結果
人数を入力してください:20
20人の点数を入力してください
1番:1
2番:34
3番:45
4番:56
5番:67
6番:78
7番:89
8番:90
9番:100
10番:100
11番:64
12番:71
13番:62
14番:843
0以上100以下の数を入力してください14番:645
0以上100以下の数を入力してください14番:87
15番:89
16番:61
17番:74
18番:76
19番:51
20番:71
---分布グラフ---
*
* *
* * *
* * * * *
* * * * * * * * *
----------------------------------
0 10 20 30 40 50 60 70 80 90 100
もうやっとできたわ。
下の点数分布の...なんていうんだこれ笑 0〜100のメモリ?みたいなのが半スペース分左によってるし、何番のところ番のいちを揃えたいから%2dにしたいけど早く次行きたいのでやめます。笑
めちゃくちゃ間違えまくって、1時間くらいかかっちゃいました。ちょっとめんどくさいとはいえやってることはとても単純なこのシステムを作るのにどれだけ時間かかってんねん笑
誰だサクッととか言ってたやつは。
まだまだ初心者の域は全く抜け出せていないみたいです笑
100のところmaxと比較していましたが、最初は上もmaxと比較していて、一番上の*しか表示されなかったり、そもそも配列の添字を間違えまくって一つ右に出ちゃったり、かっこは足りないし、*が表示されないときのスペースをelseで書くことを忘れてるし。
ひどい有様でしたが出来たので良しとしましょう。
そしてこれに似たシステムのコードが書いてあったのですが、なんでdo文を使っているのかちゃんと見てなかったのでなんでなんだろう他のじゃ出来ないっけ?と思っていましたが、いざ自分で書いてみると、腑に落ちました。一つdo文の使い道、入力してもらった値に対して判定を行い、ループを行いたいときに使うということを覚えました。他にも自分の想像力が足りないだけでたくさんあるのかな。
・まとめ
ということで、想像以上に配列のボリュームが大きかったので、今回はここまでにします!
一個気になったことがあるんですが、少し上の文章で、コードとシステムって言葉を使っているのですが、使い方は合っているのでしょうか。
コードはプログラミング言語の記述に対して、システムはプログラミング言語によって動く何かしらの機能のことを示しているつもりで使っているのですが、どなたかわかる方教えてください...
少しずつ難しくなってきましたが、まだまだ余裕はあるはずなので、突っ走っていきます!
最後まで見ていただきありがとうございました!また次回も見てくださいね!
ではまた!
この記事が気に入ったらサポートをしてみませんか?