見出し画像

中学生に説明するためのC++予習(2)


2.変数と定数(變數與常數)

 という項目を見ます。
 代数を習いはじめたばかりで、x、とかyとかもまだ目新しいはずの中学一年生にプログラミングの変数とかわかるのかね?と少々懸念しました。けれど、中学生くんは前にScratchのプログラムしたことがあるそうなので、その辺は取り越し苦労のようです。

Scratchの変数

説明するとしたら・・
・変数とは基本、Scratchでも使った「角丸長方形」の「あれ」。

Scratchではあまり気にしていなかっただろうけど、「C++」やるうえで注意することと言えば・・
・変数にはいろいろな「型」があって、厳密です。(文字、整数、浮動小数点、論理・・)
・同じ整数・浮動小数点でも「精度」や「範囲」を気にする必要がある。
・文字型と文字列型は別物。

Scratchの条件処理で出てくるYesかNoかの「横長六角形」は
「論理型」の「変数」。

といったことでしょうか?

変数名のルール

 使える文字、使えない文字。数字からははじめられないこと、大文字小文字が区別されること、C++言語で使われる予約語は使えないことといったルールは教科書に書かれている通り。

変数の型

 教科書には short int long  long long float double とか全部掲載されているけど、一覧表で見ると圧倒されちゃいそうで心配。とりあえず整数ならint 実数ならdouble だけおぼえておけばいいと思いますが・・。

教科書の演習問題に含まれている「いじわるな」問題

 「範囲」を超えてしまった時どうなるか? などという内容が、教科書の演習問題に含まれています。
(エラーになるわけではなく、範囲の「反対側」へ行ってしまう・・)

 まあ、実際にやってみるのがはやい。

整数型
short -2^15~2^15-1(-32768~32767)
int -2^31~2^31-1(-2147483648~2147483647)
unsigned short 0~2^16-1(0~65535)
unsigned int 0~2^32-1(0~4294967295)

#include <iostream>

using namespace std;

int main()
{
    short max_short = 32767;
    short max_short_plus1 = max_short + 1;

    int max_int = 2147483647;
    int max_int_plus1 = max_int + 1;

    unsigned short max_unsignedshort = 65535;
    unsigned short max_unsignedshort_plus1 = max_unsignedshort + 1;

    unsigned int max_unsignedint = 4294967295;
    unsigned int max_unsignedint_plus11 = max_unsignedint +1;

    cout << "max_int: " << max_int << endl;
    cout << "max_int_plus1: " << max_int_plus1 << endl;

    cout << "max_short: " << max_short << endl;
    cout << "max_short_plus1: " << max_short_plus1 << endl;

    cout << "max_unsignedshort: " << max_unsignedshort << endl;
    cout << "max_unsignedshort_plus1: " << max_unsignedshort_plus1 << endl;

    cout << "max_unsignedint: " << max_unsignedint << endl;
    cout << "max_unsignedint_plus11: " << max_unsignedint_plus11 << endl;

    return 0;

}

実行すると

max_int: 2147483647
max_int_plus1: -2147483648
max_short: 32767
max_short_plus1: -32768
max_unsignedshort: 65535
max_unsignedshort_plus1: 0
max_unsignedint: 4294967295
max_unsignedint_plus11: 0

という具合。

変数の概念と一緒に覚える関連知識

ストリーム

cout cinの使い方説明が一緒に出てくる。

#include <iostream>

using namespace std;

int main()
{
    int a, b;
    cout << "Input a, b" << endl;
    cin >> a >> b;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;

    return 0;
}

実行結果

Input a, b

123 456 789 と入力してみる。

Input a, b
123 456 789
a = 123
b = 456

変数二つのところに一行で三つ入力してもエラーにはならず。三つ目以降の入力は無視される。

コメントアウト

一行コメント //  の後はコンパイラには無視される
複数行コメント /*  と */ とで囲むとコンパイラには無視される

浮動小数点型の表示桁数

 教科書には<iomanip>の fixed とか setprecision()とか説明されているけど、私自身これは知らなかった。コード書いて確認してみます。
※訂正)当初書いていたテストコードは、私の理解不足から来る混乱した内容でした。理解に至る経緯は

の記事にまとめています。
当初書いていたテストコードは破棄し、ここにはあらためて修正後のコードを書きます。

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    const float x = 3.14159265358979323;
    cout << "Modified" << endl;

    cout << defaultfloat;
    cout << x << endl;
    cout << endl;
    cout << setprecision(3) << x << endl;
    cout << setprecision(4) << x << endl;
    cout << setprecision(5) << x << endl;
    cout << setprecision(6) << x << endl;
    cout << setprecision(7) << x << endl;
    cout << setprecision(8) << x << endl;
    cout << setprecision(9) << x << endl;
    cout << setprecision(10) << x << endl;
    cout << endl;

    cout << fixed;
    cout << setprecision(3) << x << endl;
    cout << setprecision(4) << x << endl;
    cout << setprecision(5) << x << endl;
    cout << setprecision(6) << x << endl;
    cout << setprecision(7) << x << endl;
    cout << setprecision(8) << x << endl;
    cout << setprecision(9) << x << endl;
    cout << setprecision(10) << x << endl;
    cout << endl;

    const double y = 3.14159265358979323;

    cout << defaultfloat;
    cout << y << endl;
    cout << endl;
    cout << setprecision(3) << y << endl;
    cout << setprecision(4) << y << endl;
    cout << setprecision(5) << y << endl;
    cout << setprecision(6) << y << endl;
    cout << setprecision(7) << y << endl;
    cout << setprecision(8) << y << endl;
    cout << setprecision(9) << y << endl;
    cout << setprecision(10) << y << endl;
    cout << endl;

    cout << fixed;
    cout << setprecision(3) << y << endl;
    cout << setprecision(4) << y << endl;
    cout << setprecision(5) << y << endl;
    cout << setprecision(6) << y << endl;
    cout << setprecision(7) << y << endl;
    cout << setprecision(8) << y << endl;
    cout << setprecision(9) << y << endl;
    cout << setprecision(10) << y << endl;
    cout << endl;


    return 0;
}

実行結果

Modified
3.14159

3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159274
3.141592741

3.142
3.1416
3.14159
3.141593
3.1415927
3.14159274
3.141592741
3.1415927410

3.141592654

3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159265
3.141592654

3.142
3.1416
3.14159
3.141593
3.1415927
3.14159265
3.141592654
3.1415926536

defaultfloat の場合は、全体の有効桁数がsetprecision()で設定した桁数
fixedの場合は小数点以下の有効桁数がsetprecision()で設定した桁数
一度行った設定はcoutに保存されているので設定内容の反映状況を比較するときは注意が必要。

エスケープシーケンス

 ウン十年前を思い出します(笑) \n で改行、\tでタブ。これは二文字ではなく特別な意味を持った一文字なんだ、というくらいを知っていればいいんじゃないかな?

常数(定数)と#define

 これも教科書のいじわる問題。#defineは単に文字列を置き換えちゃうだけという「罠があること」を知っていればよいかと。

テストコード

#include <iostream>
#define WIDTH 80
#define LENGTH WIDTH + 20

using namespace std;

int main()
{
    cout << "define test" << endl;
    cout << "area : " << (LENGTH * WIDTH) << endl;
    cout << endl;

    cout << "const test" << endl;
    const int cwidth = 80;
    const int clength = cwidth + 20;
    cout << "area : " << (clength * cwidth) << endl;

    return 0;
}

実行結果

define test
area : 1680

const test
area : 8000

検討
width 80
length 80+20で100
area width*length で8000を期待するところだけれど、define は単なる文字列の置き換えになってしまうので、
(LENGTH * WIDTH)は 80 + 20 * 80 と解釈されて1680となってしまうという引っ掛け問題。

 罠があるよ、と知っておくくらいでよいと思います。

いいなと思ったら応援しよう!