1. for ループと while ループの変換
for 文は while 文に書き換え可能である。同様に do-while 文でも実現できる。条件判定のタイミングが異なるが、制御構造の本質は同じである。C++ ではループ制御の書き換えが容易であり、可読性向上のために適宜選択する。
2. 二次元配列の文字列出力
#include <cstring>
#include <cstdio>
int main() {
char data[2][4];
strcpy(data[0], "you");
strcpy(data[1], "me");
data[0][3] = '&';
printf("%s\n", data);
return 0;
}
出力: you&me
二次元配列は行優先でメモリに配置される。data[0] には "you\0" が格納され、data[1] には "me\0" が格納される。3番目の要素に '&' を代入すると、ヌル文字が上書きされるため、文字列は "you&me" として連結される。配列名は先頭アドレスを指す。
3. const キーワードの処理時期
const int i = 10; のような宣言は「コンパイル時」に処理される。コンパイラは定数値をシンボルテーブルに記録し、以降の参照を直接値で置き換える(マクロ類似)。これにより、実行時のメモリアクセスが不要となり、読み取り専用の保証が得られる。
4. 演算子オーバーロードの制約
演算子をオーバーロードしても、元の優先順位や結合性は変更できない。また、オペランドの個数も変えられず、少なくとも1つはユーザ定義型でなければならない。構文構造(前置・後置など)も維持する。戻り値型や引数の型は自由に指定できる。
5. ポインタのサイズ(32ビットシステム)
void *p = malloc(100);
sizeof(p); // 結果: 4
32ビットシステムではポインタは4バイト、64ビットでは8バイトとなる。常に int と同じサイズとは限らないが、多くのプラットフォームで一致する。
6. ポインタの値渡しと静的変数
void modify(int *ptr) {
static int value = 4;
ptr = &value;
(*ptr)--;
}
int main() {
int num = 5;
int *ptr = #
modify(ptr);
printf("%d", *ptr); // 出力: 5
return 0;
}
ポインタを関数に渡す場合も「値渡し」である。関数内で ptr に新しいアドレスを代入しても、呼び出し元の ptr は影響を受けない。静的変数 value はデクリメントされるが、呼び出し元のポインタは元の num を指したままである。
7. オブジェクト指向プログラミングの利点
主な利点: 再利用性(継承)、拡張性(ポリモーフィズム)、保守性(カプセル化)、理解の容易さ。三大特性は「継承」「カプセル化」「ポリモーフィズム」である。
8. 配列とポインタの違い
- A: 配列は静的領域(グローバル)またはスタックに作成される。ヒープには動的配列として確保できる。
- B:
sizeof(配列名)は配列全体のバイト数を返す。正しい。 - C: ポインタは任意の型を指せるが、
const修飾により再代入不可のポインタもある(例:char* const p)。 - D:
sizeof(ポインタ)はポインタ変数自体のサイズであり、指す先の容量ではない(例:char* str = "hello"; sizeof(str) // 4 または 8)。
正解: B