本記事について
本記事は、APG4g(Go言語入門 APG4b)【1.00 ~ 1.02】の続きです。
もし、前の記事を読んでいない、もう一度見たい等ありましたら見ていただけると幸いです。
今回扱う内容は以下の通りです。
本記事での目標は、以下の3点です。
- Go言語で、四則演算とあまりの計算が出来るようになる
- Go言語で、データを保存する変数を作れるようになる
- Go言語にあるデータの型を知り、使えるようになる
では、始めていきましょう!
1.03. 四則演算と優先順位
キーポイント
演算子 | 計算内容 |
---|---|
+ |
足し算 |
- |
引き算 |
* |
かけ算 |
/ |
割り算 |
% |
割ったあまり |
四則演算
Go言語のプログラムで簡単な計算をする方法を見ていきましょう。
次のプログラムは上から順に「足し算」「引き算」「掛け算」「割り算」を行っています。
package main
import "fmt"
func main() {
fmt.Println(1 + 1) // 2 (足し算)
fmt.Println(3 - 4) // -1 (引き算)
fmt.Println(2 * 3) // 6 (かけ算)
fmt.Println(7 / 3) // 2 (割り算)
fmt.Println(-7 / 3) // -2 (負の値の割り算)
fmt.Println(7.0 / 3) // 小数の割り算
}
2
-1
6
2
-2
2.3333333333333335
これらの記号(+
,-
,*
,/
)のことを算術演算子といいます。+
,-
,*
,/
は順に、「足し算」「引き算」「かけ算」「割り算」に使う演算子(記号)です。
引き算の例のように、(+
,-
,*
,/
)を使って負の値も計算することが出来ます。
Go言語では、整数同士で割り算(/
)をした場合、小数点以下を切り捨てた値になります。
負の値の割り算も小数点が切り捨てられます。
切り捨ててほしくない場合、7.0
というように.0
をつけると、小数点以下も計算されます。
剰余演算
%
を使うことで、「割った時のあまり」を計算することが出来ます。Go言語は負の値のあまりも計算することが出来ます。
package main
import "fmt"
func main() {
fmt.Println(-4 % 3) // -1
fmt.Println(-3 % 3) // 0
fmt.Println(-2 % 3) // -2
fmt.Println(-1 % 3) // -1
fmt.Println(0 % 3) // 0
fmt.Println(1 % 3) // 1
fmt.Println(2 % 3) // 2
fmt.Println(3 % 3) // 0
fmt.Println(4 % 3) // 1
}
-1
0
-2
-1
0
1
2
0
1
演算子の優先順位
C++及びPythonの優先順位と変わりません。
- 最初に、かけ算、割り算(
*
,/
)が計算される - 次に、足し算、引き算(
+
,-
)が計算される - 括弧
()
で括られた計算があるなら、括弧の中の計算が優先される
ゼロ除算(細かい話)
Go言語ではゼロで割っても実行時エラーになりません。
※ただし、数値を直接指定してゼロ除算をしている場合はコンパイルエラーを起こします。
package main
import "fmt"
func main() {
zero := 0.0
pinf := 1.0 / zero
ninf := -1.0 / zero
nan := zero / zero
fmt.Println(zero, pinf, ninf, nan)
// fmt.Println(1.0 / 0.0) // ./d_1.03c.go:12:20: invalid operation: division by zero
}
0 +Inf -Inf NaN
このように、0や正/負の無限大、NaN(Not a Number)として計算されます。
参考資料
練習問題
EX3 - 計算問題を解いてみましょう。
解答(解けなかったら開いてください)
package main
import "fmt"
func main() {
fmt.Println(100 * (100 + 1) / 2)
}
補足
なぜ、
\frac{1}{2} \times 100 \times (100 + 1)
をそのまま計算すると不正解となってしまうのか?を説明します。
結論から言うと、1 / 2
は整数の割り算の切り捨て処理によって、0
となってしまうからです。
実は、1.0 / 2.0
とすることで回避できます。(0.5
になる)
ですが、割り算は最後に計算するというプログラムを書いたほうが、数値計算として誤差が出にくくなるため、割り算は最後に書いたほうが良いと思います。
package main
import "fmt"
func main() {
fmt.Println(1 / 2)
fmt.Println(1.0 / 2.0 * 100 * (100 + 1))
}
0
5050
1.04. 変数と型
キーポイント
- 変数は「メモ」
-
=
は代入 - 「データの種類」を「型」と言う
型 | 書き込むデータの種類 |
---|---|
int | 整数 |
float64 | 小数 |
string | 文字列 |
変数
変数という機能について見ていきましょう。変数は「メモ」や「ふせん」というイメージがいいかもしれません。
メモはこのようなイメージです。詳しくは後述します。
- 変数名 : メモのタイトル
- 型 : メモに書いてあるデータの種類と紙の大きさ
- 値 : メモの内容
例を見てみましょう。
package main
import "fmt"
func main() {
var variable_1 int = 10
var variable_1a int
variable_2 := 20
fmt.Println(variable_1, variable_1+10)
fmt.Println(variable_1a, variable_1a+10)
fmt.Println(variable_2, variable_2+10)
}
10 20
0 10
20 30
宣言と代入
変数を使うには最初に「宣言」を行う必要があります。
変数を宣言する方法には2種類ありますが、どちらを使っても構いません。
変数を宣言する時は、変数の名前を指定します。
var variable_1 int = 10 // 明示的型付け
var variable_1a int // 明示的型付け その2
variable_2 := 20 // 暗黙的型付け
1行目の明示的型付けで宣言を行う場合、最初にvar
を付けます。
その後に変数名(variable_1
)を書き、最後に型(int
)を付けます。
2行目の暗黙的型付けの場合は変数名(variable_2
)を書き、:=
を書いて、その後にメモの内容となる値(データ)を書きます。
※暗黙的型付けの場合、明示的型付けで行うような型の指定はコンパイル時に自動的に解釈されます。
宣言した変数にデータをメモする時は、=
を使って代入をします。
また、宣言時に値を同時に代入することを初期化と言います。
明示的型付けの場合は初期化をする必要がありませんが、暗黙的型付けの場合は:=
を使った初期化が必要です。
変数のコピー
変数1 = 変数2
というような形で書いた場合、変数の値そのものがコピーされます。
その後に変数の値を変えても、もう片方の変数に影響はありません。
package main
import "fmt"
func main() {
var a int = 10
var b = a
a = 40
fmt.Println(a, b)
}
40 10
変数を同時に宣言
変数の宣言時に,
を入れることで、複数の変数を同時に宣言することも出来ます。
package main
import "fmt"
func main() {
var a, b int = 10, 5 // 明示的型付け
c, d := 20, 25 // 暗黙的型付け
fmt.Println(a, b)
fmt.Println(c, d)
}
10 5
20 25
さらに、明示的宣言の場合は()
で囲んで改行区切りで書くことで、1つのvar
で複数行に渡って変数を宣言することが出来ます。
package main
import "fmt"
func main() {
var (
a int
b int
c int = 5
d int = 10
)
fmt.Println(a, b, c, d)
}
0 0 5 10
変数のルール
変数は基本的に自由につけることが出来ますが、一部の名前を変数名にするとコンパイルエラーを起こします。
利用できない変数名
以下の条件に該当する変数名は変数名に出来ません。
- 数字で始まる名前
-
_
以外の記号が使われている名前 - キーワード(Go言語が使っている一部の単語)
例えば、以下のコードはエラーになります。
package main
import "fmt"
func main() {
var 100hello int
var na+me
var go int
fmt.Println(100hello, na+me, go)
}
./e_1.04e.go:6:6: syntax error: unexpected literal 100, expected name
./e_1.04e.go:7:8: syntax error: unexpected +, expected type
./e_1.04e.go:8:6: syntax error: unexpected go, expected name
./e_1.04e.go:9:17: syntax error: unexpected hello in argument list; possibly missing comma or )
以下のような変数名は大丈夫です。
var hello10 int
var hello_world int
同じ変数名の変数は宣言できない
同じ名前の変数を複数回宣言することは出来ません。
package main
import "fmt"
func main() {
var a = 0
var a = 5
fmt.Println(a)
}
./e_1.04f.go:7:6: a redeclared in this block
./e_1.04f.go:6:6: other declaration of a
型
int
以外にもGoには様々な型があります。
ここでは重要な3つの型を紹介します。
型 | 書き込むデータの種類 |
---|---|
int | 整数 |
float64 | 小数 |
string | 文字列 |
package main
import "fmt"
func main() {
i := 10
f := 0.5
s := "Hello"
fmt.Println(i, f, s)
}
10 0.5 Hello
異なる型同士の計算
Go言語では異なる型同士の計算が出来ません。
異なる型同士の計算をしようとすると、コンパイルエラーとなります。
package main
import "fmt"
func main() {
a := 1
b := 1.5
fmt.Println(a * b)
}
./e_1.04h.go:9:14: invalid operation: a * b (mismatched types int and float64)
異なる型同士の代入
Go言語では異なる型同士の代入も出来ません。
異なる型同士の計算と同様にコンパイルエラーとなります。
package main
import "fmt"
func main() {
i := 1
var d float64 = i
fmt.Println(i, d)
}
./e_1.04i.go:7:18: cannot use i (variable of type int) as float64 value in variable declaration
細かい話
変数の細かい話です
Go言語ではint
はキーワードではないので、
var int int
という変数宣言が可能です。
(コードを読む際に混乱することになるので、書くべきではありません)
package main
import "fmt"
func main() {
var int int // intの初期値は0
fmt.Println(int)
}
0
Go言語のキーワードについては、Keywords - The Go Programming Language Specificationを御覧ください。
練習問題
EX4 - ◯年は何秒?を解いてみましょう。
package main
import "fmt"
func main() {
seconds := 365 * 24 * 60 * 60
// 文字列の部分を消して追記する
fmt.Println("1年は何秒か")
fmt.Println("2年は何秒か")
fmt.Println("5年は何秒か")
fmt.Println("10年は何秒か")
}
解答(解けなかったら開いてください)
package main
import "fmt"
func main() {
seconds := 365 * 24 * 60 * 60
// 文字列の部分を消して追記する
fmt.Println(seconds)
fmt.Println(seconds * 2)
fmt.Println(seconds * 5)
fmt.Println(seconds * 10)
}
第一章 (1.03 - 1.04) おわりに
APG4gの1.03 - 1.04までの内容は以上です。お疲れさまでした。
以降の内容は別途投稿する予定です。
より良い書き方がありましたら適宜ご指摘お願いします。