2020/09/03

エド君と学ぶC講座6

今回の内容 配列 関数の作成



アイスなエド君おいしそう…


エド君「なんか変なこと言ってるやつがいるが今回は配列の話だ。配列は変数を1つにまとめて番号を振ることで管理しやすくなるものという感覚で覚えてくれれば良い。例えばだがオレやコイツのように2人だけならデータもそんなに多くなくて良いがもし10人、100人文のデータが必要になった場合に変数をそんだけ作っていたら大変だし無駄すぎる。それを簡単にするためのものだ。例えばだが…今回はエル捜索隊(エルソードのメンツのいるチーム的なやつ)の男性陣の身長とその平均を出すプログラミングを作る。」
エド君の身長しか知らんわ。
エド君「他のやつにももう少し興味持て。」
ブーメラン刺さってね?
エド君「うるせぇ!」

#include<stdio.h>

int main(void) {
    int i;
    int height[7];
    int sum = 0;

    printf("身長を入力してください。\n");
    for (i = 0; i <7; i++) {
        printf("%d番", i + 1);
        scanf("%d", &height[i]);
        sum += height[i];
    }
    printf("平均:%.1f", (double)sum / 7);
    return 0;
}



エド君「…ん?男は6人しかいねぇはずだが…」
あ、最後の私だな。
エド君「オマエは関係ねぇだろうが!!」
ひどいな!?仲間だろう!?
エド君「エルソ知らねぇやつが混乱するからそういうこと言うんじゃねぇ!」
でもほらエド君私平均に近い。
エド君「じゃあオマエ抜いてもあまり数値変わんねぇな。」
ひでぇ!!(なお実際に6人で計算した場合は171.7でした。ほんとにあんま変わんなかった。)

こう見ると大人組でかくない?うちの子でも180超えそんないないんだけど。
一番平均に近いのはエド君かあ。カワイイ。
エド君「何がカワイイかわかんねぇが解説していくぞ。今回使ったheight[7]ってやつが配列だ。これで7つの身長を入れる箱ができたわけだな。ちなみに箱の数字は0から始まるから厳密にはa[n-1]まで、つまり今回だと0~6の範囲の数字となる。」

int a[3]={1,2,3};

エド君「このように最初に初期化することもできる。入れてない所は0で初期化がされる。」
なるほど。そういや途中でコピーさせたいときはそのまま代入演算子でいける?
エド君「ああ、それだがforで1つずつコピーする必要があるな。」
めんどいな…
エド君「キーボードから入力する際も今回みたいにforを使うのがやりやすいな。#defineというのを使ってマクロで数字を置換することもできる。」

#include<stdio.h>
#define NUMBER 7
int main(void) {

    int i;
    int height[NUMBER];
    int sum = 0;

    printf("身長を入力してください。\n");
    for (i = 0; i < NUMBER; i++) {
        printf("%d番", i + 1);
        scanf("%d", &height[i]);
        sum += height[i];
    }

    printf("平均:%.1f", (double)sum / NUMBER);
    return 0;
}

エド君「今回は7という数字をNUMBERで置き換えた。」
でもこれめんどくさくない?むしろ文字数増えてるし。メリットあるのか?
エド君「こうすることのメリットだが数字を置き換えたいときにdefineのとこの数字さえ変えれば全部置き換わるから楽というところだな。さっきのだと全部の数字を変える必要があったからな。」



エド君「あと数字を入力された逆の並びでだすこともできるぞ。」

#include<stdio.h>

int main(void) {
    int i;
    int a[7];
    int sum = 0;

    for (i = 0; i <7; i++) {
        printf("a[%d]:", i );
        scanf("%d", &a[i]);
       
    }
 
    for (i = 0; i < 3; i++) {
        int b = a[i];
        a[i] = a[6 - i];
        a[6 - i] = b;
    }
    printf("反転結果\n");
    for (i = 0; i < 7; i++)
        printf("a[%d]=%d\n", i, a[i]);
    return 0;
}


おおすごい。どういう技術だこれ。
エド君「今回の場合7個あるから2つめのforでi番目と6-i番目を入れ替えるプログラムを用意した。」


エド君「さっきまでは一次元の配列だったが活用すれば多次元の配列も作れるぞ。」

int a[3][2]={{1,2},{3,4},{5,6}};

エド君「こういう感じだな。2個はいる配列が3個あるって解釈になる。」
なるほど…



エド君「さてと配列の話はこれくらいだな。実際のとこなんだがここら辺まで分かっていれば自分で関数を作ってちょっと複雑なプログラムもできるようになる。」
関数を作る?
エド君「ああ。むしろ本格的なものを作るなら自作する必要が出てくるからな。簡単に大きい数字を判別する関数を自作してみるぞ。」


#include<stdio.h>

int max(int x, int y) {
if (x > y)
return x;
else
return y;
}

int main(void) {
int a, b;
printf("エド君「数字を2つ入力しろ。」\n");
printf("a:"); scanf("%d", &a);
printf("b:"); scanf("%d", &b);
printf("エド君「大きい方の数字は%dだ。」",max(a, b));

return 0;
}

エド君「int mainの所とは別にmaxという関数で大きさの比較をするようにしたぞ。mainの中でmaxが出てきたところで呼び出すシステムになっているから先に書いたから先に動くということはない。あと自作関数はmainの後ろに置くこともできるんだが…」

#include<stdio.h>

int max(int x,int y);

int main(void) {
int a, b;
printf("エド君「数字を2つ入力しろ。」\n");
printf("a:"); scanf("%d", &a);
printf("b:"); scanf("%d", &b);
printf("エド君「大きい方の数字は%dだ。」",max(a, b));

return 0;
}

int max(int x, int y) {
if (x > y)
return x;
else
return y;
}

エド君「どっちみちmainの前に関数の宣言がいるから前に書いた方が手間が省けるんだけどな。まあこういうのを応用すればいろいろな関数を自分で作れるようになって幅が広くなる。あとポインタとか構造体とかもあるんだが…こういうのはややこしいからな。またそのときになれば話すとするか。」

エド君と学ぶC講座5

今回の内容 簡単な復習 C言語の性質 ミスしがちな内容





エド君「さて今回は箸休めとでもいくか。まずは今までにやってきた関数の簡単な整理をしていく。」

・printf 文字の出力。%dで10進数、%fで浮動小数点数を出すことができる。その他に%u、%sなどもあるがこれは使うときにまた…

・scanf キーボードから入力された値を格納する。格納したい変数の前には基本的に&を
つけるがつけないものもある。これの説明も使うときに…

・puts printfと似ているが自動的に改行が入る。

・putchar 1文字のものを出力する際に使う。'A'のように'で文字を囲む。

・if 式を評価しその条件に合うかで分岐させる。else ifやelseと組み合わせて使うことが多い。

・switch 複数の分岐があり、式が同じ場合にはこっちのほうが使いやすい。

・do do~whileで使う。他のループ系に比べるとあまり使わない。

・while do文が判定が1度実行された後に対して実行前に判定される。こっちの方が使うが条件次第ではループが1度も実行されないこともある。

・for 最大3つの式で条件や行動を表す。制御式(真ん中の式)以外は省略することもできるが制御式を省略すると無限ループと化す。


エド君「まあこんなところだな。さてここからはC言語のちょっとした性質の話をするか。まずは識別子…変数とかに使うやつだな。これの制限の話だ。これは先頭が非数字、2文字目以降は数字でも非数字でもよくなっている。」
つまりはx1はいけるけど1xはいけないってことか。
エド君「ああ。あと大文字と小文字は区別されるからABCとabcは別の識別子になる。非数字のなかにはアンダーバー(_)も使えるがそれ以外の記号とかは使えねぇ。abc@とかはできないわけだな。」
つまりはtako_addは識別子として使えるのか…
エド君「あとはifやforのように変数に使えないものもある。まあ基本的には既存の関数やそこで使うものは対象外ってことだ。」






そういやプログラム見てるとなんか字下げされてるけどあれっていったい?
エド君「インデントの話だな。段落中のものをずらして書くと構造がわかりやすくなるというのと環境によっては並べると不都合が起きることもあるんだよ。あとそういう風に書くと読みやすい。C言語には記述にある程度の自由さがあるんだが…」



#include<stdio.h>

int main(         void) { printf("Hello world!"
);
    return 0
        ;
}

エド君「こんな書き方でも動くのは動くが…わかりにくいだろ?」
これはひどい。
エド君「自由形式自体は認められてはいるが流石に見る側につたわりにくすぎる。初歩的なhalloworldでこのざまだからな。さらに複雑な内容だと自分で見直したときにも混乱しかねない。あと自由形式とはいえ例えばintやreturn、演算子の間に空白を入れるとエラーになるし最初にあるincludeのような#がつく処理は分離ができねぇ。」

#include
<stdio.h>

エド君「こう書くとエラーになる。」
そういえば長文書きたいときに行変えるとエラーになったんだがあれってどうすりゃいいんだ?
エド君「たまにあるやつだな。中身が長くなって見づらくなること。」

printf("口は悪いけどほんとは優しいし抱えてる闇深すぎるしギャップがカワイイ。
そう。エド君はカワイイんだよ。");

こういうのを入れたかったんだが…
エド君「文章が変なのは置いといてそういう場合は行ごとに"で囲むといい。」

printf("口は悪いけどほんとは優しいし抱えてる闇深すぎるしギャップがカワイイ。"
        "そう。エド君はカワイイんだよ。");

エド君「こうすりゃ長文でも見やすくなる。あと個人で見返す時や相手にわかりやすいプログラミングを作るならコメントの挿入をするといい。」
コメント?
エド君「ああ。例えばだが…」


/*読み込んだ数字は奇数か偶数か*/
#include<stdio.h>

int main(void) {
    int x;
    printf("エド君「数字を入力しろ。」");
    scanf("%d", &x);
    if (x % 2)

        printf("エド君「その数は奇数だ。」"); //2で余りが出る。
    else
        printf("エド君「その数は偶数だ。」"); //2で割り切れる。
    return 0;
}

エド君「/**/や//でコメントをつけることができる。複数人での作業なら必須だな。こういうのを残しておくとどういう動作なのかとかがわかりやすくなる。あとは初心者がやりがちなミスとかの話もするか。」

・stdio.hをstudioとかく。

エド君「英単語のほうで書きがちなミスだ。」
あるわ…stuまで書いてあ、違うってなるやつ。
エド君「動かねぇと思ったらそもそもここが違っていたというオチだな。」

・半角と全角を間違える。

エド君「出力される文字とかなら全角でも良いんだが括弧やセミコロン、空白が全角になっていてエラーになることがある。ここは半角でやるということを覚えるしかねぇな。それでもたまにやらかすんだが。」
あー…これ空白が全角だとわかりにくいな…気をつけねば。

・綴りのミス。

エド君「まあ最初のもこれなんだが動かないと思っていたらprintfがprinfになってたとかあとこれはPythonとかしてるとやりがちなんだがprintで書いて動かないってパターンだな。」
Python?
エド君「そういうプログラミング言語があるんだよ。あっちだとprintで動くからfを付け忘れるとかな…」

・=と==の間違い。

エド君「=は代入==は等しいかの判別なんだがそもそも==を使うべき所で=を入れてエラーになるもありがちなミスだな。」
どうしてもa=bで2つが等しいって認識になってしまうんだよなあ…

・;の付け忘れ

エド君「printfとかの後ろは;をつける必要があるんだがこれを忘れることも多い。あと逆のパターンとしてforとかのつけなくて良いところでつけてしまうこととかもな。」
なんにでもつけて良いわけじゃないのか…困ったらつけとけば解決…ともいかないんだな。

・変数の宣言し忘れ。

エド君「変数を複数使っていたり途中で増やしたいとなったときに宣言漏れが起こるときがある。」
確認大切だな。

・配列の範囲の勘違い。

エド君「配列に関しては次の回でやる予定なんだが先にミスしやすいとこを言っておくと
int a[10]ってなってるやつはこの10は0~9の10個で10番目は10じゃなくて9になるという仕様がある。つまりa[9]までしかないということだ。」

・{}の数が合わない。

エド君「{で始めたら}で閉じる必要があるんだがこれの数が合わずにエラーになる、括弧の位置がおかしくて挙動が合わないという事が起きる。とくに長文になると数がわかりにくくなるんだよなこれが…」
んでどこに入れたら良いかわからなくなるやつ…つらみ。

・そもそもなんでエラーが起きているのかがわからない。

エド君「そんな馬鹿なとなりそうだが以外と何が原因なのか分からないとかエラー表示はないのに動かそうとしたらエラーを吐くとかな…まあ表示される場合はそのエラーを読めば良いんだが英語表示も多くてわからねぇってやつもいるな…」
あるある…できたと思って起動したら例外がどうのこうのって出てなにも分からないとき…
エド君「分からないときに相談できる相手がいるとプログラミングは特に心強いんだが…」
やめろ。私みたいな陰キャにはエド君くらいなんだよ頼れるの。






エド君「さて。今回は小休憩だったが次からはまたいろいろと教えていくぞ。次回は途中でも語った配列の話だ。」


2020/08/26

エド君と学ぶC講座4

今回の内容 do文 while文 for文



エド君「ちょっと日が空いたが今回は繰り返し文…つまりループさせる文についてだ。」
つまりソシャゲによくある周回作業みたいなもんか。
エド君「まあ…間違っちゃいねぇけど…今までは1回しかできなかったプログラムを数回繰り返すためにこれを使うぞ。まずはdo文からだ。前に奇数か偶数か判定するプログラムを作ったがまずはこれを1回の起動で数回できるように変える。」

#include<stdio.h>

int main(void) {
 int x;
 printf("エド君「数字を入力しろ。」");
 scanf("%d", &x);
 if (x % 2)

  printf("エド君「その数は奇数だ。」");
 else
  printf("エド君「その数は偶数だ。」");
 return 0;
}

エド君「前回のがこれだな。do文を使うときにはdoとwhileの間にループさせたいプログラムを入力する。大体こんな感じだな。」

#include<stdio.h>

int main(void) {
    int a;
    do {
        int x;
        printf("エド君「数字を入力しろ。」");
        scanf("%d", &x);
        if (x % 2)

            printf("エド君「その数は奇数だ。」\n");
        else
            printf("エド君「その数は偶数だ。」\n");
        printf("エド君「もう一度するなら0,やめるなら1を押せ。」");
        scanf("%d", &a);
    } while (a == 0);
    return 0;
}



おおすごいな。これでループできるのか…
そういやこのwhileってのはどういう条件になってるんだ?
エド君「これはこの条件に合う間はループさせるって感じの文だな。0が入力されてる間はループされる。あと今回ループを終わらせるときに1を入力させるように促してるが実際の所は0じゃないものなら終了はする。あとdo文には読み込む値の制限を設けることもできる。例えば…」
do{
scanf("%d",&a);
}while(a<0||a>2)

エド君「このようにすれば0,1,2以外の数字が入力されるともう一度入力するように促すことができる。3択でできるものならこんな感じのループをつくると良さそうだな。ここで1つ論理否定演算子についても話しておくか。前にa!=bという演算子を載せたが似たものに!aという演算子がある。これはaが0なら1をそうじゃないときに0を返す演算子だ。さっきのwhileのやつだが…こんな風に書き換えることもできる。」

!(a>=0&&a<=2)

エド君「この場合はaが0以上かつ2以下でないという条件になるな。こんな感じのものを活用したド・モルガンの定理というものがある。簡単に説明すればこんな感じだ。」

a&&b=!(!a||!b)
a||b=!(!a&&!b)

エド君「あと複合代入演算子とかの話もしておくか。複合代入演算子は+=などの2つの演算を行う演算子だ。」

b+=a

エド君「こうすることでbにaの値を加えることができる。これを使えばループで数字を複数入力してその合計を求めることもできるわけだ。まあ今のだとb=b+aと同じと思ってくれていい。あとは後置と前置の増減を行う演算子の話だが…ここでクイズだ。」

a=9のときの++aとaとa++

エド君「この場合どんな数が出力されると思うか?」
なんかプラスの位置が違うな。真ん中のはそのまま9が出るとして両方とも10になるんじゃないのか?
エド君「不正解だ。++aは10だがa++は9のまま出力される。」
そうなのか…
エド君「わかりにくい場合は1足してからaが出るかaを出してから1足すかという認識で覚えるといい。」
なるほど…
エド君「余談だがこれはそれぞれを並べずに出したときであってもし仮に…」

printf("%d,%d,%d",++a,a,a++);

エド君「こんな感じにするとすべての数が10になる。原理は分かるな?」
最初ので10になってあと二つは出力時に加算されないからか。
エド君「そういうことだ。先に増減させるものを前置演算子、後で増減するものを後置演算子と呼ぶ。ここらへんはプログラムを読みやすくするからちゃんと覚えておけ。」



エド君「さて次はwhile文だ。まあdo文に出てきたwhileと同じだがこっちは後ろにつけていたものを前に持ってくる。例としてカウントダウンを行うプログラムを作ってみるか。」



ちょっと気になったんだがそれならそもそもdo文っているのか?
エド君「基本的にはwhileでいけるがdo文の特徴として1回は実行されるという点がある。whileだと条件式次第ではそもそも実行されないということもあるからな。これは式の評価がどこのタイミングにあるかの違いだな。」

#include<stdio.h>

int main(void) {
    int a;
    printf("エド君「数字を入力しろ。」");
    scanf("%d", &a);
    while (a >= 0)
        printf("%d ", a--);
    printf("\n");
    return 0;
}

エド君「こんな感じで任意の数字から0までのカウントダウンができるようになる。」
もしかしてなんだがこれカウントアップのほうもできるのか?
エド君「ああ。任意の数字までカウントアップしたいという場合にはもう一つ変数を置いてそれが入力された数字になるまで増加させれば良い。」

i=0;
while(i<=a)
printf("%d",i++);

エド君「まあscanfの後ろをこんな感じにすればいけるな。そういえばprintfを今まで使っていたがputsやputcharという関数もあるぞ。」
どこら辺が違うんだ?
エド君「putsを使えば自動で改行をしてくれる。例えばだが奇数偶数のプログラムの結果を表示するところはこっちでもいけるわけだ。あとprintfだと%を文字として出すには%%とする必要があったがputsは一個でいい。putcharは文字を1文字出力ができる。」

putchar('*');

エド君「こうすると*が出る。このとき間違えやすいのが”と’を混同してしまうことだ。」
printfとは違うのか…
エド君「ここら辺もうまく使い分けていけ。最後はfor文だ。これはちょっと方式が違ってきてforの中に最大3つの式を入れて条件をつけていく。さっきのカウントダウンをfor文にしてみるか。」

#include<stdio.h>

int main(void) {
    int a;
    int i;
    printf("エド君「数字を入力しろ。」");
    scanf("%d", &a);
    for(i=a;i>=0;i--)
        printf("%d ", i);
    printf("\n");
    return 0;
}


エド君「大体基本としてはこんなもんだ。このように前処理、制御式、後処理みたいな感じで分かれているがもし処理が必要ないなら省略することもできる。前処理を入れてわかりやすくするために変数iを使ったが効率よくするなら今回これはいらねぇ。こうすりゃいい。」

#include<stdio.h>

int main(void) {
    int a; 
    printf("エド君「数字を入力しろ。」");
    scanf("%d", &a);
    for(;a>=0;a--)
        printf("%d ", a);
    printf("\n");
    return 0;
}

エド君「何も入れずにセミコロンだけ入れれば省略ができる。」
ほかのとこの省略できるのか?
エド君「ああ。後処理でやることがないならそこも省略できる。制御するとこを省略すると無限ループと化すけどな。」
なんかfor文が一番使いやすそうに感じるな…あと無限ループってこわくね?
エド君「まあ実際使う機会もおおいからな。他にも(i=2;i<=n;i+=2)にすると偶数だけ並べるとかもできる。まあ規定回数までループさせるときに使いやすいのは強みだな。」

エド君「for文は組み合わせることもできる。いわゆる多重ループだな。図形とか作るときにも使えるテクニックだ。例えば長さを入力して長方形を作るプログラミングなら…」

#include<stdio.h>

int main(void) {
    int a,b;
    int i,j;
    printf("エド君「縦の長さを入力しろ。」");
    scanf("%d", &a);
    printf("エド君「横の長さを入力しろ。」");
    scanf("%d", &b);
    for (i = 1; i <= a; i++) {
        for (j = 1; j <= b; j++) {
            putchar('*');
        }

        printf("\n");
    }
    return 0;
}



エド君「…(いつの間にか書き換えられているテキストに目を背ける)」
どうしたエド君?
エド君「ま、まあこんな感じで2つのループを行うことができるわけだ…」
これなかなか便利そうだな。
エド君「ああ。これを使ってピラミッドを作ることもできる。」
ピラミッドってこんなかんじのやつ?

   エ
  エド君
 エド君すこ
エド君カワイイ

エド君「いや確かに形はそうだが変なピラミッド作ってんじゃねぇ。ピラミッドを作るにはfor文を3回使う。」
結構ややこしいんだな。

*
**
***

エド君「こんな感じの三角形ならそこまで複雑じゃねぇんだけどな。ピラミッドになると空白の処理も必要になる分ややこしくなる。」

#include <stdio.h>
int main(void) {
    int a;
    int i, j, k;
    printf("エド君「ピラミッドの段数を入力しろ。」");
    scanf("%d", &a);
    for (i = 1; i <= a; i++) {
        for (j = 1; j <= a - i; j++) {
            putchar(' ');
        }
        for (k = 1; k <= i * 2 - 1; k++) {
            putchar('*');
        }
        printf("\n");
    }

    return 0;
}


エド君「ピラミッドを作るときに各段の数が2個ずつ奇数で増えるからi*2-1で奇数の数列になるように設定している。」
なるほど。iが段数、jが空白部分、kが*の配置ってことか…

エド君「さて。今回はこの辺にしておくか。次はちょっと箸休めにプログラミングでミスしやすい点やプログラムの要素、今までにやったことの簡単なおさらいとするか。まあ肩の力抜くことも大切だからな。」


2020/08/21

エド君と学ぶC講座3

今回の内容 if文 演算子 switch文



そういえばこのエド君のカットインが近いうちに実装されるらしい。本家KRでは実装された。



エド君「今回はif文というのをやる。今までのプログラムは一本の線で繋がってるようなないようだったが今回のは分岐要素を入れてより複雑にしていくぞ。」
全部1つで済ませれたら楽なのにな。
エド君「人生も選択の連続だろうが。」
まあ確かにそうだ。エド君の2次職の分岐もあるもんな。
あ、そうかそういう分岐をプログラムに起こすときに使うって事か。
エド君「まあたとえ方が極端だが…そんなもんだ。」

エド君「まずは簡単な分岐からだ。入力された数字が奇数か偶数かを判定するプログラムを作るぞ。if文の作り方だが例えば…」

if(x>2)

エド君「こんな風にifの後の括弧に条件を入れてその条件に合う場合の行動を下に書いていく。違う条件の時にはelse ifやelseで分岐させる。大体はこんな感じだ。例とし…」

#include<stdio.h>

int main(void) {
int x;
printf("エド君「数字を入力しろ。」");
scanf("%d", &x);
if (x % 2)

printf("エド君「その数は奇数だ。」");
else
printf("エド君「その数は偶数だ。」");
return 0;
}





エド君「ここに書いてたはずのやつがなんか変な感じにされてるな…」
やっぱエド君にしゃべらせるのが一番かなと思いまして。
エド君とのやりとりって感じにしたくて。
エド君「まあいいが…今回の場合だと奇数の判定のためにxを2で割った余りが1になるなら奇数、そうでないなら偶数という分岐をさせている。」
このx%2ってどういう判定してるんだ?
エド君「簡単に言えば余りが0じゃないとき…まあ余りが出るときという判定だな。」


エド君「次は演算子の話をするか。」
演算子?
エド君「大なり小なりとかの話だ。さっきの例でつかったやつだがちょっと複雑なやつもあるからな。とりあえず一覧として載せておく。」


演算子意味(判定が合えば1,合わなければ0を返す)
a==b等しいかの判定
a!=b等しくないかの判定
a<baがbより小さいか
a>baがbより大きいか
a<=baがb以下か
a>=baがb以上か
a?b:caが非0ならb、そうでないならc
a&&bAND
a||bOR


エド君「まあ大体はこんな感じだ。a?b:cがちょっとややこしいかもしれねぇな。」
なるほど。
エド君「極論言っちまうとifで分岐させちまえばできるんだが…まあ覚えといて損はねぇ。ANDやORを使えば何月かを入れて季節を表示するようなプログラムも作れるぞ。」

if(month>=3&&month<=5)
printf("春です");

エド君「こんな感じのを季節分作っていけばまあできる。」
3~5月の判定になるのか。
エド君「この場合冬だけがちょっと厄介だけどな。」

else if(month==1||month==2||month==12)

エド君「こんな感じでORを2回使う感じになる。」
数字が飛ぶからか…


エド君「さてもう一つ分岐系の文を紹介しておくか。次はswitch文だ。if文に比べて多くの分岐がしやすいのが特徴だな。例えばだが任意の数で割った余りを出すプログラムを作ろうとする。まあ3あたりで良いか。if文だとどう作る?」
そうだな…

#include<stdio.h>

int main(void) {
int x;
printf("エド君「数字を入力しろ。」");
scanf("%d", &x);
if (x % 3==0)

printf("エド君「その数は3で割りきれる数だ。」");
else if(x%3==1)
printf("エド君「その数は3で割ると1余りが出る数だ。」");
else
printf("エド君「その数は3で割ると2余りが出る数だ。」");
return 0;
}

こんな感じか?
エド君「これを見てなにか思ったことはないか?」
いや別に…
エド君「そうか…実はこの内容だと無駄なところが出てくるんだが…同じ演算を2回してるだろ?」
あー…でも他に方法なくね?
エド君「そのためにswitch文があるんだよ。今のやつを書き換えると…」

#include<stdio.h>

int main(void) {
int x;
printf("エド君「数字を入力しろ。」");
scanf("%d", &x);
switch (x%3)
{
case 0: printf("エド君「その数は3で割りきれる数だ。」"); break;  
case 1: printf("エド君「その数は3で割ると1余りが出る数だ。」"); break;
case 2: printf("エド君「その数は3で割ると2余りが出る数だ。」"); break;

}

return 0;
}


エド君「こんな感じになる。簡単に言えば余りの数字をcaseとして分岐させてるといったとこだ。注意点としてはcaseと数字の間に空白を入れること。入れないとcase0みたいな識別子だと認識されるからな。ちなみにこのbreakはswitch文を抜け出すためのコマンドだ。これをつけなかった場合はbreakのあるところまで反映されるようになる。あとはどのcaseにも当てはまらないとき用に使えるdefaultというものもある。」
結局どっちがいいんだ?
エド君「分岐数が多いならswitchの方がいいが2分岐くらいならifの方が良いとも聞くな。」
まあ分岐の種類次第か。
エド君「あとはswitchだとさっき言ったa?b:cの三項演算子が使えないらしいが正直なところ複雑な書き方すると一気にわかりにくくなるのが三項演算子だからな…あ
とCならまだしもC#とかになると似た記号表現が出てきてややこしいって問題もある。ただ学生ならこの三項演算子という概念をテストで問われる可能性もあるしやっぱり記憶の片隅にでもいれとくのは悪くねぇぞ。」



エド君「というわけで今回は終わりだ。ちなみにこの二つの文を合わせて選択文と言ったりもする。次はループ系の関数だ。これも種類がいくつかあるから混乱しねぇようにな。」




2020/08/20

エド君と学ぶC講座2

今回の内容 四則演算 浮動小数点数




エド君「前回はほんとに基礎なことだったが今回は計算をうまく活用していこうと思うぞ。浮動小数点数とかも教えていく。まずは四則演算と余りの数を出す方法だ。」


#include<stdio.h>

int main(void) {
int x=30, y=9;
printf("x=%d,y=%d\n",x, y);
printf("x+y=%d\n", x + y);
printf("x-y=%d\n", x - y);
printf("x*y=%d\n", x * y);
printf("x/y=%d\n", x / y);
printf("x%%y=%d\n", x % y);

return 0;
}



エド君「足し引きはわかりやすいがかけ算は*、割り算は/を使う。余りは%だが文章の中に%を入れたいときは2個並べる必要があるぞ。」

でもこれって単純なことだよな?
エド君「まあこれだけなら簡単だな。ただこの形だと割り算のときに整数しか出ない。もし小数点も出したかったらどうする?」
さっき言ってた浮動小数点数ってやつか?
エド君「それだ。例えばこんな式があったとしよう。」
21÷2
エド君「これを11.5で出したいが今のだと11としか出ない。そこでdoubleで小数点を出すわけだ。他にも平均値を出すときにも使いやすいな。そうだ。3つの数の平均を出すプログラムを作ってみろ。ヒントとして平均を出す式を教えてやる。」

(double)sum/3;

エド君「まあsumは合計の数値だ。こっちの式の作り方は流石にわかるよな?ちなみにだが式の前に(double)と入れると答えが浮動小数点数になる。あとdoubleを使うときは%dじゃなくて%fになるからそこは注意しろ。」
なるほど…つまりはこうか!

#include<stdio.h> int main(void) { int x, y,z; int sum; double ave; printf("エド君「数字を3つ入力しろ。」\n"); printf("x="); scanf("%d", &x); printf("y="); scanf("%d", &y); printf("z="); scanf("%d", &z); sum = x + y + z; ave= (double)sum / 3; printf("エド君「合計は%dで平均は%fだ。」\n", sum,ave); return 0; }


エド君「オレの台詞になってるのが謎だがまあそんなところだな。」
でもなんか小数点の数多いなあ。これ2桁くらいにできないのかね?
エド君「ああ、それなら%.1fや%.2fとかで調整できるぞ。」
なるほど。
エド君「短いが今回はここまでにするか。」
次のやつ難しい感じ?
エド君「いや、難しいというよりやることがだいぶ変わってくるからな。分けた方が良いと思っただけだ。あれこれ言っても混乱するだろ。」

2020/08/18

エド君と学ぶC講座1

今回の内容 printf、scanf 変数 代入 初期化

この記事はC言語むずいなと思ったたこ焼きがメモみたいな感覚でエド君と学んでくコンテンツです。参考になるかは知らぬ。
ちなみにVisual Studioを使用してますが後に語るscanfというコマンドでエラーが出てしまうのでSDLチェックをいいえにして対応する必要があります。



べつの環境使うなら多分気にしなくても良いやつ。



エド君「…でなんでオレが教えないといけないんだよ。」
いやあエド君こういうの得意そうだから。

エド君「チッ…じゃあまずはhalloworldからやるか。これを入れてみろ。」

#include<stdio.h>

int main(void) {
printf("Hello world!");
return 0;
}



おお、なんか出てきたな。しかしなぜhalloworldなんだ?エド君カワイイでもよくないか?
エド君「もともと昔にあったC言語の本で紹介されてから一番最初はこれをやるところが多くなったらしい。確かになんでも良いがオレはカワイクねぇ。」
つまりはこのprintfが文字を出すコマンドなわけか。
エド君「まあそういうことだ。出力したい文字は””の中に入れて括弧の終わりの次には;をつける。これを忘れるとエラーが起きるぞ。」
このint mainとかincludeは一体?
エド君「基本的なプログラムで使うやつだ。まあ土台だな。基本的にはこれを入れてint mainの中に実行したいプログラムを書いていくと覚えれば良い。時々説明で省略することもあるが実際に試すときには書くようにな。」
つまりはまじないみたいなもんだな。

エド君「他にも計算結果を出力することもできるぞ。printfの中身をこうしてみろ。」

printf("%d",9+11);

おお。確かに20になるな。でも%dってなんだ?
エド君「こいつは10進数で表示するときに使うやつだ。ちなみにこのdが10進数の語句に由来してるぞ。」
へえ…ということは他の進数にもできるのか。
エド君「8進数なら%o、16進数なら%xと聞くな。あまりつかわねぇとは思うけどな。」
2進数は?
エド君「2進数はねぇ。必要なら独自で実装しろ。他にもいろいろとあるがそれはまた使うときに話す。」
この%dとかと文字も組み合わせれるんだな。なるほどじゃあ2つの数字の和は○○ですみたいな文章もできるわけだ。
エド君「文章で思い出したが長い文とか行を分けたいって思う時が出てくるんだがそのときには\n(\のキーとn)を入れれば次の行にうつすことができる。」
なるほどな。

printf("エド君カワイイね…\n大天使エドエルだ。");


確かになるな!
エド君「文がおかしい気もするがまあ…そういうことだ。」






エド君「じゃあ次は変数だ。」
変数?
エド君「つまりは数字や文字を代入させて見やすくするってことだ。わかれ。今まではprintfの中に数字を入れていたが変数で入れて表示させるぞ。」

#include<stdio.h>

int main(void) {
int x,y;
x = 9;
y = x + 10;

printf("x=%d,y=%d",x,y);
return 0;
}


おお。xやyに数字を代入して出力された。
エド君「こんな風に代入の際に別の変数を使うこともできる。ちなみに基本的に数字の変数はintでいいが浮動小数点数を出すためのdoubleというものもある。変数を1つずつintで置くこともできるがその文行数は増えるからどっちが良いかは状況次第だな。」
そういえばもしxとyに数字代入しなかったらどうなるんだ?
エド君「試してみろ。」

…エラーになった。
エド君「オマエの環境だと出ないのか。変数は生成されるときに適当な数字が入れられる。だから変な数字になったりまあものによっては0が入るやつもあるかもしれねぇな。もし入れたい値がもうあるのなら初期化の際に入れるといい。こんな感じだな。」

・int x=9,y=x+10;

・int x=9;
   int y=x+10;

エド君「どっちでも良いが下の方が見やすい感じはある。」
初期化と代入とでタイミングが違うんだな。
エド君「先に入れておくか後から入れるかだな。」

なるほど…確かに便利だけど数字を変えたいときにわざわざ書き換えるのめんどくさいなあ。任意の数字を打ち込めるようなのないのか?
エド君「そのためにあるのがscanfという関数だ。これは変数に打ち込んだものを格納することができる関数になっている。例えばこんなものを入れてみろ。」

#include<stdio.h>

int main(void) {
int x;
printf("任意の数字を入れてください");
scanf("%d", &x);

printf("%dがにゅ


あ、改変してみて良いか?
エド君「ま、まあいいが…」

#include<stdio.h>

int main(void) {
int x;
printf("エド「任意の数字を言ってみろ。」");
scanf("%d", &x);

printf("エド「%dだな?」",x);
return 0;
}


おっとコンマが入り込んだから消しとかねば。
エド君「いやなんだよこれ…間違ってはねぇけどよ…」

やっぱ遊び心あったほうが楽しいだろう?
なるほどな。なんか楽しくなってきたな。
scanfのときは変数の前に&がいるのか。
エド君「これ意外と忘れてなんか違う答えになったとかエラーが起きたとかもあるから気をつけろよ。」


エド君「さて初回だし今回は本当に基礎のここらへんで終わっておくか。」
そういやこれ数字じゃなくて文字を入力したいときは何使えばいいんだ?
エド君「また後に話すから落ち着け。順序ってもんがあんだよ。」




2020/08/14

アイカツ!はどこにいってしまうんだろう~アイカツプラネット編~

※このブログはアイカツ!はどこにいってしまうんだろう~過去の作品編~の続きとなっています。こちらを見なくても問題は多分ないですが読んで貰えると理解して貰いやすいかと…
https://addloving.blogspot.com/2020/08/blog-post_11.html



さてここまでアイカツの過去のシリーズを語ってきたが問題となる新作
アイカツプラネットの話にいこうか。


想定外すぎる展開だらけで困惑してる人、これはアイカツだと認められない人、これもアイカツだと思える人、まあいろいろいるとは思うんだが私は正直否定的な方だ。





これだけ見ればちょっと派手な女の子たちのアイドルアニメという感想で終わるし私としても普通に継続して見てみても良いとは思う。とはいえそもそもの内容の時点で問題が多すぎるんだが。そこら辺は後に語っていく。

まず勘のいい人やアイカツシリーズを追いかけてきた人だとこの時点でん?となる部分があるかもしれない。







ロゴマークだ。

ここで初代アイカツとオンパレードのロゴを見てみよう。




さて何が違うかが分かっただろうか。
まずフォントが違う。
初代アイカツのフォントはスターズ、フレンズでも同じようなものが使われている。しかしプラネットではそこからが違うのだ。
だからどうしたと言われそうだがアイカツシリーズとしての繋がりが薄れているような感覚に私は陥った。また周りにあったカードが消えているという点もあるがこっちはかなり深刻な問題なので後に詳細に語りたいと思う。ちなみにスターズ、フレンズにもカードは配置されている。





さてこれだけならまだ良かったのだがとんでもないコンテンツにシフトした。

https://www.aikatsu.com/planet/

画像として載せることすら私はしたくないので公式サイトのリンクをはっておくがこの作品…なんとアニメと実写を融合してしまったのだ。

確かに過去のアイカツでは歌唱担当が分かれていてその人達のライブというものはあったがそれはその人達のファンが行けばいいものであり作中では特に扱われてはいない。
しかし作中に実写パートが入ってしまえばそれを回避することはできない。
実写というのはかなり好みの分かれるコンテンツであり、新しい作品で作るならまだしもアイカツという長年続いたジャンルに突然放り込んでいいものなのかというのが疑問なのである。
どうやら今回の作品はアバターとして2次元のアイドルとして活動するというようなテイストなのだがそれは今までのアイカツを否定するんじゃないかという点も気になっている。
仮に歴代のアイカツシリーズを走り抜けたアイドル達とプラネットのアイドルが並んだときに一人だけリアルな方の姿だと明らかに浮くしならアバターで出したとするとそこに並ぶいちごたちも所詮は2次元の存在であると言われているような感じになる。
一人のアイドルからキャラクターの一人になってしまうような感じがしてしまうわけだ。
なんならプラネットのアバター姿だけホログラムみたいな描写して並べてくれればその不安も消えてくれるのだが…

またストーリー面のほうも少し気になる。




これは公式サイトのあらすじのようなやつなんだが…これを見たとき女児向け特撮のファントミラージュを思い出した。
この特撮系人気あるのか今4作まで出てるらしいがそのうちの一つがひみつ戦隊ってコンセプトでバレたら姿を変えられてしまうとかいうやつがあるらしい。
まあこの設定的にはガワ借りてますみたいな感じなんだろうが。

今の女児はそういう実写系の好きなのかね?
まあそういうのが好きな子ならいいんだろうが今までのアニメのアイカツを見てきた子達が実写を受け入れられるのかが問題だと思う。
結局私がこう語っていてもメインターゲットは女児なんだよな。
だからそこの層に受けるなら問題はないんだろうが今まで応援してきた子が離れる可能性もあるわけで。

ちなみに私は幼い頃から実写ってのが苦手でかつてNHKにあった料理アイドルのアニメもアニメパートは好きだけど実写パートはいらないなと思ってたりディズニーのアニメと実写を融合した映画もアニメだけでいいのにって思ってる人間でした。既にあの頃からオタクの血が流れていた。今も作品の実写化とか舞台化とか聞くとやめてほしいと思う。




ここで一番の問題点 カードの概念についてを語ろうと思う。
アイカツにおいて大切なものは何かと言われればアイカツカードと言っても過言ではないくらいにはカードが命な世界だ。
というのもアニメアイカツ1話のアイカツ格言なのだが…






この通り

芸能人はカードが命

なのである。
もう一度言おう。

芸能人はカードが命



後々にもう一度格言になるくらいには大切なこと。



オンパレードでも引き継がれるほど。







あかりにとっては大切な味方。





そんな存在だったわけだ。
ここまで語ればアイカツを知らないという人にもカードの大切さが多少は伝わるのではないだろうか。



しかしプラネットにはカードがない。
カードではなくスイングというものを使いドレシアという精霊的なやつの力を借りるらしい。



これがスイングなのだが…
ここまで語ってきた芸能人はカードが命という概念はどこにいった?
命やぞ?マストアイテムやぞ?それ捨てたらアイカツ消えるぞ?


マジでこんな感じ。
しかもアイドル活動がバトルステージときた。いやアイドルだよな?
バトルってなんだよ。
確かに対決する機会はちらほら過去にもあった。でも本質はそこじゃないんだよ。
バトルに勝ってドレスに着替える?そうじゃないんだよ。
根本からずれてるんだよそれならアイカツじゃなくていいじゃないか。もう別のアイドルアニメとして作ればいいじゃないか。


あと肝心のドレスも正直なこと言うとダサい。


最高レアと言われて納得するんだろうかってくらい派手さがない。アバターはめちゃくちゃ派手なのに服が負けてる。

下手したらRドレスにも負けてないか…?


Nに至ってはこの有様である。


本来のアイカツにおけるNは私服のような衣装というようなデザインだったんだが流石にアレを私服にする人おらんやろ…
まあ試作段階の可能性もあるしな。…そうだよな?
本稼働時にもうちょいおしゃれになってるだろ。なっててくれ。


あと問題点としては演技力の部分だ。
そもそも実写に重みを置いているのか声優ではなく俳優や実際にアイドルとして活動している子を起用しているらしいが実写パートならそれでいいのかもしれない。
ただ問題はアニメパートになったときだ。
アニメとしての演技とドラマとしての演技は全く違う。
プロモーション映像を開いたときの最初の感想はなんだこの棒演技は!?だった。
女児向けの特撮と割り切ればこれくらいのレベルなんだろうとも思えるんだが仮にもアニメでこの声をされるとさすがにキツイ。
歌にも問題があり、確かに女児向けの特撮としての曲ならいいんだが歌を歌うシーンとなればおそらくはアバター姿であろう。
BBフェスで公開されたやつを聴くと歌声が致命的にアニメに合ってないのだ。きつすぎる。無理だ。
もしかしたら音源として収録しているやつが多少マシである可能性はなくもないが期待しすぎない方が良いだろう。
中には歌うまいと言ってる人もいるんだがひとつのユニットとして評価している気がする。アニメキャラがこの歌声だったらちょっと無理あるだろ…そこら辺は指導とかでアニメにあった歌声になってくれることを期待したいが…





アイカツがこのまま成功すれば実写の道になりそうだし失敗して戻ってくれるとありがたいが大コケした結果アイカツシリーズ自体がなくなるのも怖いジレンマ…
せめていちごたちアイドルが繋いできたバトンは落とさないでほしいものだ…












そんな思いを抱えながら久しぶりにアイカツがしたくなってゲーセンへ行った。
なんてことない毎日がかけがえないというカレンダーガールの歌詞が脳裏に浮かんでその曲にしようと思った。

そしたらドレスセレクションがちょうど1期の最終回である50話をピックアップしていた。カレンダーガールが入っていたのだ。
そしてプレイしたらいちごのステージドレスが出てきた。



星宮いちごの原点はこのドレスだったんだよな…
そんな気持ちになった夏の日。