Chapter 04

整数の出力と四則演算

対応する APG4b の箇所:1.03.四則演算と優先順位

フォーマット出力

プレースホルダーを値で置き換える

今までは, println!/print! マクロで単に文字列のみを出力していました.しかし, println!/print! マクロではこんなこともできます.

fn main() {
    println!("最小の素数は{}です.", 2);
}

println!( ) の括弧内には文字列リテラルを書くといいました.今回は文字列リテラルに加え,コンマ(,)で区切ってさらに 2 という整数が書かれています.このようにプログラム中に直接書かれた整数を整数リテラルといいます.

文字列リテラルを見ると,その中に {} という括弧が存在します.これはプレースホルダーと呼ばれます. println! マクロは,プレースホルダーが存在すると,文字列リテラルの後に続いているものを参照し,プレースホルダーの部分をその値で置き換えます.つまり,今回は {} の部分が 2 で置き換えられて,最小の素数は2です. と出力されることになります.

今回 {} の括弧の中身は空ですが,この中で詳細なフォーマットを指定することもできます.とりあえず今は {} が値で置き換えられるということだけを覚えておいてください.

単に値だけを出力して改行したいときは

fn main() {
    println!("{}", 2);
}

とすれば良いです.

次のコードはエラーになります.

fn main() {
    println!("{}");
}

プレースホルダーだけがあって,そこに置き換わる値が存在しないからです.エラーメッセージは

error: 1 positional argument in format string, but no arguments were given
 --> src/main.rs:2:15
  |
2 |     println!("{}");
  |               ^^

のようになります.

複数個のプレースホルダー

プレースホルダーは複数個あってもかまいません.

fn main() {
    println!("{}の次の完全数は{}です.", 6, 28);
}

ここでは,「文字列リテラル "{}の次の完全数は{}です."」,「整数リテラル 6」,「整数リテラル 28」の 3 つが,コンマ区切りで書かれています.1 つ目のプレースホルダーは 6 , 2 つ目のプレースホルダーは 28 で置き換えられ,6の次の完全数は28です.と出力されます.

四則演算

整数同士で演算を行うことができます.ここでは次の 5 つを紹介します.

演算子 意味
+ 足し算
- 引き算
* かけ算
/ 割り算の商
% 割り算のあまり

たとえばこんなコードが書けます.

fn main() {
    println!("2 + 3 = {}", 2 + 3);
}

このコードでは,println!( ) の括弧の中身は,「文字列リテラル"2 + 3 = {}"」と「式2 + 3」の 2 つです.式 2 + 3 が計算されて 5 という値になり,文字列リテラルのプレースホルダーに埋め込まれて,出力される内容は 2 + 3 = 5 となります.

このコードでは,コンマ , の直後や演算子 + の前後に空白文字が入っています.この空白文字は書かなくても動きますが,あった方が見やすいため入れるのが良いとされています.

同様に,引き算やかけ算は

fn main() {
    println!("5 - 2 = {}", 5 - 2);
    println!("3 * 4 = {}", 3 * 4);
}

のようにできます.

割り算については,次のようになります.

fn main() {
    println!("14を3で割ると,商が{}であまりが{}です.", 14 / 3, 14 % 3);
}

プレースホルダーが 2 つあるので, 1 つ目のプレースホルダーは 14 / 3 の値, 2 つ目のプレースホルダーは 14 % 3 の値で置き換えられます.

14 / 3 は割り算の商, 14 % 3 は割り算のあまりです.よって今回は 14を3で割ると,商が4であまりが2です. と出力されることになります.

優先順位

たとえば,

fn main() {
    println!("{}", 5 + 3 * 2);
}

のように,足し算とかけ算が混ざった式を書くと,かけ算の方が先に計算され,結果は 5 + 6 = 11 になります.5 + 3 を先に計算したければ,括弧でくくります.

fn main() {
    println!("{}", (5 + 3) * 2);
}

これを演算子の優先順位といいます. *+ より優先順位が高いということになります.+- の優先順位は同じです.*/% の 3 つの優先順位は同じです.

今後他の演算子も登場しますが,全て優先順位が定まっています.

また,優先順位が同じ演算子が並んでいた場合,結合順序に従って順序が決まります.+- の 2 つ,そして */% の 3 つは左結合といって,左から順に計算されます.すなわち

fn main() {
    println!("{}", 7 / 2 * 2);
}

は,まず 7 / 2 が計算されて 3 となり,その後に 3 * 2 が計算されて結果は 6 となります.

問題

ここまでの内容を使って,この問題を解いてみましょう.

問題文
Aくんは1から100までの和を求めようと思いました。
数学の授業で習ったとおり、1から100までの和は次の式で求められます。

\frac12 \times 100 \times (100+1)

この式の値を出力してください。

クリックで解説を表示

1 / 2 を先に計算しようとすると,余りが切り捨てられて 0 になってしまいます.そこで, 100 * (100 + 1) / 2 のように,最後に 2 で割ることで正しい答えになります.

fn main(){
    println!("{}", 100 * (100 + 1) / 2);
}

また,問題文には明記されていませんが, println!print! に変えると WA になります.競技プログラミングでは出力の最後に改行が求められることが多いです.