1. 変数 int:なぜ必要で、どう扱うか
最初はプログラムの中の数は「ノートに書くように」使えると思いがちです:2 + 2 と書けばそれで良い、と。しかし実際のプログラムは通常一行だけで完結しません。データを保持し、それを変更し、計算結果を何度か使い、異なる場所で結果を表示します。だからこそ「この数は重要だ」と名前を付けて参照できる方法が必要です。
int 型はそのための最も基本的な道具です。これは整数を格納します: 0、7、-12、42。 小数部分はありません。int は「整数を入れる箱」で、その箱にラベル(変数名)を書いて混乱を避けると考えるとよいでしょう。
宣言、初期値、代入
変数を作るときは2つのことをします:名前を考え、型を選びます。つまりそこに「何が入るか」を決めます。多くの場合、その場で初期値を与えて変数が「空」にならないようにします(C++ では特に重要です)。
最小の例を見てみましょう。ここでは特別なことはせず、年齢を保持して表示するだけです。しかしほとんどのプログラムはこうして始まります:データからです。
#include <iostream>
int main() {
int age = 18;
std::cout << "Age = " << age << '\n'; // Age = 18
}
注目すべき点が3つあります。まず、int age = 18; は「age という名前の int 型変数を作り、そこに 18 を入れる」と読めます。 次に、std::cout には文字列も数値も << 演算子で連結して出力できる点です。 最後に、改行文字 '\n' によって出力が整います。
重要なのは、変数は定数ではないということです。その値は代入によって変更できます。
#include <iostream>
int main() {
int score = 0;
std::cout << score << '\n'; // 0
score = 10;
std::cout << score << '\n'; // 10
}
ここでは score = 10; が「古い値を新しい値に置き換える」ことを意味します。プログラミングにおける = は通常「等しい」ではなく「代入する」を表します。
2. int の算術と式の括弧
整数に対する操作 +、-、*
int の算術はとても馴染みやすく、期待どおりに動きます:加算、減算、乗算は期待通りです。 ただし重要な点があります:結果も整数になります。今は当たり前に聞こえますが、除算のところで特に影響が出ます — 後で詳しく扱います。
まずは基本:和、差、積を計算します。
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a + b) << '\n'; // 9
std::cout << (a - b) << '\n'; // 5
std::cout << (a * b) << '\n'; // 14
}
ここでは括弧は必須ではありませんが、初心者には助けになります:計算したいことが明確になり、式を難解にしてしまう可能性が減ります。
結果を変数に保存するのも有用です。こうするとコードが読みやすくなります:まず計算してから使う、という流れになります。
#include <iostream>
int main() {
int apples = 3;
int pears = 4;
int total = apples + pears;
std::cout << total << '\n'; // 7
}
括弧:意味と可読性のために
式が長くなると、脳はコンパイラと同じように計算の順序を考え始めます。しかし人間は疲れるし忘れます。だから良いスタイルは「人に分かりにくいところには括弧を置く」ことです。 これは弱さではなく、将来の自分やコードをチェックする人への配慮です。
同じ意味を持つ場合でも、見た目が違うだけで読みやすさは大きく変わります。
#include <iostream>
int main() {
int x = 10;
int y = 3;
int r1 = x + y * 2;
int r2 = (x + y) * 2;
std::cout << r1 << '\n'; // 16
std::cout << r2 << '\n'; // 26
}
括弧は意味を変えます。重要な式は目で見て明らかにしておくのが良い、というルールを覚えておきましょう。
3. /(除算)と %(余り)について
/:結果は常に整数
/ 演算子は int に対しては整数除算を行います。 つまり結果も int であり、小数は数学的に四捨五入されるのではなく単に切り捨てられます。
古典的な例で確認してみましょう:
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a / b) << '\n'; // 3
}
なぜ 3 であって 3.5 ではないのか? それは int が .5 を表現できないからです。 整数部分だけを取り出し、残りを捨てます。
この挙動は「いくつの完全なグループができるか」を数えるときには便利です。例えば、6 個入りのパックがあって 25 個のクッキーがあるとき、何パック作れるか、などです。 しかし「本当の」除算を期待している場合には危険です。 int 同士の / は int を返す、というルールだけは覚えておきましょう。
負の数についても結果は整数になります。近年の C++ では小数部分の切り捨てはゼロ方向に行われるため、 -7 / 2 は -3 になります。
#include <iostream>
int main() {
int a = -7;
int b = 2;
std::cout << (a / b) << '\n'; // -3
}
「さて、余りはどうなるの?」と思ったなら、それは良い疑問です。次は % です。
%:除算のあとの残り
% 演算子は「除算の余り」と読みます。 これは整数にのみ使えます(ここでは int)。 典型的には「箱に分ける」「お金を両替する」「整数で割り切れるかを確認する」などの問題で使います。
基本的な例:
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a % b) << '\n'; // 1
}
つまり 7 個のオレンジを 2 人で分けると、 各人に 3 個ずつ行き、余りが 1 個残る、ということです。
除算と余りは次の式で結び付けて覚えると便利です: a = (a / b) * b + (a % b)
これは魔法ではなく、単に「数 a は b のいくつかのグループと余りから成る」と言っているだけです。
コードで確かめてみましょう:
#include <iostream>
int main() {
int a = 25;
int b = 6;
int q = a / b; // いくつの完全なグループか
int r = a % b; // いくつ残るか
std::cout << q << '\n'; // 4
std::cout << r << '\n'; // 1
}
まだおもちゃのように見えるかもしれませんが、いくつか問題を解くと % を至る所で見るようになります: 時計の時間、偶奇判定、ページ分割、秒を分に変換するなどです。
4. ゼロで割ることは許されない
数学ではゼロ除算は定義されていません。プログラミングでは実用上の問題になります: 式 a / 0 や a % 0 は許されません。 プログラムはクラッシュしたり、まったく予測できない動作をしたりします(さらに厄介なのはエラーが「後でどこかで」現れることです)。
重要なのは恐れることではなく習慣です:割る側(除数)がゼロになり得るなら、それをチェックする習慣をつけること。 まだ if を学んでいないので今日のルールは簡単です:例題と初級問題ではゼロで割らないこと。除数はゼロ以外であると意識してください。
5. ミニアプリ:「自販機(販売機)と硬貨」
ここでは現実世界らしい小さなプログラムを書きます:所持金と商品の価格があり、2つのことを求めます。 ひとつは何個買えるか、もうひとつはいくらお釣りが残るか。これは / と % にぴったりの問題です。
注意:まだ入力処理を学んでいないので数値はコード内にハードコードします。今日は入力ではなく算術が目的です。
バージョン1:個数とお釣りを計算する
例えば 275 セント(つまり $2.75)を持っていて、クッキーが 60 セントだとします。計算しましょう。
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int cookies = moneyCents / cookiePrice;
int change = moneyCents % cookiePrice;
std::cout << cookies << '\n'; // 4
std::cout << change << '\n'; // 35
}
変数の利点がここではっきり分かります:価格と所持金を一度定義すれば、その後の計算で何度も使えて、シナリオを変えたいときもコードを書き換える量が少なくて済みます。
バージョン2:出力をわかりやすくする
今は出力が「機械的」な数の羅列なので、ラベルを付けてコンソール風に見せます。 文字列型は次の講義で扱いますが、引用符で囲った文字列を出力することは既にできます。
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int cookies = moneyCents / cookiePrice;
int change = moneyCents % cookiePrice;
std::cout << "Cookies: " << cookies << '\n'; // Cookies: 4
std::cout << "Change: " << change << " cents\n"; // Change: 35 cents
}
これでちょっとしたアプリらしくなりました。
バージョン3:さらにもう一つの買い物
クッキーを買った後に 35 セントのガムを買いたいとします。お釣りがあるので買えるか計算してみます。 これはまた / と % の出番です。
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int gumPrice = 35;
int cookies = moneyCents / cookiePrice;
int changeAfterCookies = moneyCents % cookiePrice;
int gums = changeAfterCookies / gumPrice;
std::cout << "Cookies: " << cookies << '\n'; // Cookies: 4
std::cout << "Gums: " << gums << '\n'; // Gums: 1
}
ここでは変数が「処理の物語」を保つ手助けをしているのがよくわかります。単に計算するだけでなく、処理の流れを記述しています。
6. int、/、% に関する典型的な間違い
間違いその1:期待してしまうこと — 7 / 2 が 3.5 を返すと期待すること。
これは初心者によくある罠です:学校で習った数学を覚えている脳が働きますが、プログラムは int の世界で動きます。 整数除算では小数部分が切り捨てられます。小数が必要なら別の話題になります。今日は整数の世界のルールを受け入れましょう。
間違いその2:% を何でもかんでも使うこと。
余り演算は便利ですが「万能ボタン」ではありません。% は「等しいグループに分けたあとの残り」を意味します。言葉で「何が残るか」を説明できないなら、% を使うべきではないことが多いです。プログラミングでの当てずっぽうは安全ではありません。
間違いその3:忘れがちなこと — a % 0 や a / 0 は許されない。
ゼロ除算は単にエラーを出すだけでなく、計算の論理を破壊します。除数はゼロでないことを常に意識してください。条件分岐(if)を学んだら入力を守る方法を学びますが、現時点ではゼロを除数にしないでください。
間違いその4:括弧を省略して長い式を書き、その結果を理解できない。
コンパイラは正しく解釈しますが、人間は必ずしもそうではありません。結果が違う理由が分からなくなります。括弧はバグ予防の安価で効果的な手段です。
間違いその5:「変数を作る」と「変数を変更する」を混同する。
int x = 10; は変数を初期化して作ることを意味します。 一方で x = 10; は既存の変数に代入することです。同じスコープ内で同名の変数を二度宣言するとコンパイラがエラーを出します:すでに x が存在すると指摘されます。
GO TO FULL VERSION