UE5 使ってると C++ のコード読むケースがままあるけど、そのたび「わからん」となっていました。
たまたま古本屋で独習C++ が安く売っていたので、いい機会だと思って読んでみることにしました。
ざっと読み進めながら、気になった部分だけメモします。
P8
C++ は変数の初期値が不定とのこと。C# が初期値がデフォルトで存在することも触れられている。C# に慣れてしまっていると省略してしまいそう。
初期化に 4 通りも書き方がある。 =
やら :=
を使う言語しか使ってこなかったので variable-name(initial-value)
は面白いです。
P14
main
の return
は省略できる。なんだってーーーーー!
P18
sizeof
の話。日頃 Web 系な人間には型のサイズなんて何に使うんだって気持ちになる。char
は常に 1 byte らしい。マルチバイト文字を扱う場合には違う型か配列とかで処理すんのかな。
P29
switch
の default
は省略可能。(C# も書かないと IDE がうるさいけど省略できるか)
P36
型の話。
signed int
:int
と同じunsigned int
: 負数は扱えないlong long
:long
と同じかより広い (すごい名前だ)
P37
void foo()
も void foo(void)
も同じ。引数が空であることにも使うのか。
P40
そうだったのか!
P40
ついにポインター
type*
ポインター型- 変数のアドレスを格納する
int* pi = 3
とすると、pi
はポインター変数と呼ばれる
&variable
アドレス演算子- 変数のアドレス取得
*variable
間接参照演算子- アドレスの変数を間接参照する
- 上記だと、
pi
を間接参照するには*pi
とし、そこで3
の値が得られる。
func(type* param)
のように関数の引数にポインター型を指定できる
P42
「constポインター」という名前だが、const なのは「ポインターの先の値。つまり *
で間接参照された値」。よって、ポインター自体は書き換え可能。
const type-name* variable-name; OR type-name const* variable-name;
「const なポインター変数」は、そのままポインター変数が const ということなので、ポインター自体は書き換え不可。一方で先の値は変更できる。
type-name* const variable-name = initial-address;
正直、記法がわかりにくすぎる。。せめて const*
の書き方はやめて欲しい。
P45
ヌルポインター
- ポインター変数を
0
で初期化でヌルポインターにできる。 nullptr
リテラルでも同じ。- アドレスが無効ということなので、間接参照すると Segmentation fault する
if (ptr == nullptr)
のチェックができる
P48
キャスト演算子
static_cast<target-type>(expression)
でキャストできる。static と付いているのには意味があるんだろうな。
P52
配列
C# と似てるかとおもいきや、変数名に []
をつけるらしい。型の方じゃないんだな。
Ruby 書いてると配列が万能過ぎて勘違いしそうになるけど、長さは決まっていると。
配列のコピーはがつっとはできないらしい。
// NG int source[] = {0, 1, 2}; int dest[3] = source; // OK int dest[] = {source[0], source[1], source[2]};
まあ、なんか便利関数とかありそうだけど。
P56
文字列の話。char
の配列で作成。ヌル終端文字列分の長さが必要。
昔大学で C を書かされた時にやったようなやらなかったような。。
そのまま std::string
に。現代感。
練習問題にかかれているが、ヌル終端文字列が途中で入ると、文字列だろうと、std::string
だろうとそこで終了という扱いになるようだ。
P59
ループ処理
for
, while
, do-while
に加えて、foreach
的な for
もある。
continue
, break
もあるので、ここは迷いなくいけそうな感じ。