変数・データ型・演算子
問1データ型
x に 3.14 を代入するための正しい型を答えよ。
[1] x = 3.14;
[1]:
答え: double
3.14 は浮動小数点数。精度の高い double を使うのが標準。
問2書式指定子
int型 n を10進で、double型 f を小数2桁で表示する。
printf("n=%[1], f=%[2]\n", n, f);
[1]: [2]:
答え: [1] d, [2] .2f
問3複合代入
最終的な a の値は?
int a = 7;
a += 3;
a *= 2;
a %= 7;
a =
答え: 6
7 → 10 → 20 → 20%7 = 6
問4型変換
int同士の商を double で受けるにはキャストが必要。
int a = 7, b = 2;
double r = [1]a / b;
[1]:
答え: (double)
片方を double にキャストすることで浮動小数点除算になる。
問5インクリメント
実行後の b の値は?
int a = 5;
int b = a++ + ++a;
b =
答え: 12
a++=5で a=6、次に++aでa=7,値は7 → 5+7=12
問6sizeof
多くの処理系で sizeof(int) の結果は何バイトか。
答え: 4
32bit/64bitの多くの環境で int は4バイト。short:2, long:8, double:8 も覚えておく。
問7整数除算
printf("%d\n", 7 / 2); の出力は?
答え: 3
整数同士の割り算は小数点以下を切り捨てる。3.5 ではなく 3 になる。
制御構文(if / for / while)
問8if文
80以上で"A"、60-79で"B"、それ以外は"C"を出力。
if (score >= 80) printf("A");
[1] (score >= 60) printf("B");
[2] printf("C");
[1]: [2]:
答え: [1] else if, [2] else
問9for文
1から10までの総和。
int sum = 0;
for (int i = [1]; i [2] 10; i++) {
sum += i;
}
[1]: [2]:
答え: [1] 1, [2] <=
問10while・出力予測
出力を順に答えよ。
int n = 10;
while (n > 0) {
printf("%d ", n);
n /= 2;
}
出力:
答え: 10 5 2 1
問11switch
フォールスルーを防ぐキーワードは?
switch (op) {
case '+': r = a + b; [1];
case '-': r = a - b; [1];
default: r = 0;
}
[1]:
答え: break
問12do-while
printfは何回実行されるか。
int i = 0;
do {
printf("*");
i++;
} while (i < 0);
回数:
答え: 1
do-whileは最低1回実行してから条件判定。
問13break と continue
以下のコードの出力は?
for (int i = 1; i <= 5; i++) {
if (i == 3) continue;
if (i == 5) break;
printf("%d ", i);
}
出力:
答え: 1 2 4
i=3 は continue で飛ばす、i=5 は break でループ終了。
問14ネストループ
次のコードで printf は何回実行されるか。
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
printf("*");
回数:
答え: 12
3 × 4 = 12 回。
問15三項演算子
a と b の大きい方を max に入れる。三項演算子で書け。
int max = (a > b) [1] a [2] b;
[1]: [2]:
答え: [1] ?, [2] :
cond ? 真の値 : 偽の値 の書式。
配列・文字列
問16配列初期化
要素数5のint配列 a を {10,20,30,40,50} で初期化。
int a[[1]] = {[2]};
[1]: [2]:
答え: [1] 5, [2] 10, 20, 30, 40, 50
問17配列走査
出力は?
int a[5] = {1, 2, 3, 4, 5};
int sum = 0;
for (int i = 0; i < 5; i++)
if (a[i] % 2 == 0) sum += a[i];
printf("%d\n", sum);
出力:
答え: 6
偶数 2, 4 の和。
問18文字列終端
C言語の文字列終端文字(Cソース表記で)。
答え: \\0
問21配列を関数に
int配列と長さを受け取り、合計を返す関数のシグネチャ。末尾セミコロンまで。
答え: int sum(int a[], int n);
int *a でも同義。関数内では配列はポインタに退化する。
関数・再帰・スコープ
問23プロトタイプ
int 2つを受け取り int の和を返す関数 add のプロトタイプ宣言(セミコロンまで)。
答え: int add(int a, int b);
問24return
値を返すキーワードは?
int max(int a, int b) {
if (a > b) [1] a;
else [1] b;
}
[1]:
答え: return
問25再帰(階乗)
fact(n) を完成させよ。
int fact(int n) {
if (n <= 1) return [1];
return n * fact([2]);
}
[1]: [2]:
答え: 1, n - 1
問26フィボナッチ
fib(0)=0, fib(1)=1, fib(n)=fib(n-1)+fib(n-2) で fib(6) は?
fib(6) =
答え: 8
0,1,1,2,3,5,8
問27値渡し
出力は?
void swap(int x, int y) {
int t = x; x = y; y = t;
}
int main(void) {
int a = 3, b = 5;
swap(a, b);
printf("%d %d\n", a, b);
}
出力:
答え: 3 5
Cは値渡しなので呼び出し元は変わらない。
問28スコープ
次のコード、内側の { } を抜けた後の x の値は?
int x = 10;
{
int x = 20;
// ここではxは20
}
printf("%d\n", x);
出力:
答え: 10
内側のxはブロックを抜けると消え、外側のxが見える。
問29グローバル変数
次のプログラムの出力は?
int g = 0;
void add(int x) {
g += x;
}
int main(void) {
add(3);
add(4);
printf("%d\n", g);
}
出力:
答え: 7
グローバル変数 g は全ての関数から共有される。
問30static 変数
次の関数を3回呼ぶと何を出力する?
void count(void) {
static int n = 0;
n++;
printf("%d ", n);
}
// count(); count(); count();
出力:
答え: 1 2 3
static変数は関数を抜けても値を保持し、次回呼び出し時に引き継がれる。
ポインタ・構造体・動的メモリ
問32配列とポインタ
正しいものを全て選べ(例: A,C)。
A: 配列名 a は先頭要素のアドレス
B: a[i] と *(a+i) は同義
C: sizeof(a) と sizeof(&a[0]) は常に等しい
D: 関数引数の配列は sizeof で要素数が取れない
正解:
答え: A, B, D
問33構造体メンバ
アクセス演算子を答えよ。
struct Point { int x, y; };
struct Point p = {3, 4};
printf("%d\n", p[1]x);
struct Point *pp = &p;
printf("%d\n", pp[2]y);
[1]: [2]:
答え: ., ->
問34malloc/free
int n個分を動的確保して解放。
int *a = (int*)[1](n * sizeof(int));
/* use */
[2](a);
[1]: [2]:
答え: malloc, free
問36NULLチェック
malloc 失敗を検出するにはどう書く?
int *a = malloc(100);
if (a == [1]) { /* エラー処理 */ }
[1]:
答え: NULL
if (!a) とも書ける。
問37メモリリーク
次のコードにはバグがある。何か(1語で)。
void leaky(int n) {
int *a = malloc(n * sizeof(int));
return; // free がない!
}
答え: メモリリーク
malloc で確保して free しないと、メモリが解放されず残る。
問38ポインタ演算
以下のコードで *p はどの要素を指すか(配列の値で答えよ)。
int a[] = {10, 20, 30, 40, 50};
int *p = a;
p += 3;
*p =
答え: 40
ポインタ演算は要素単位。+3 で a[3] = 40 を指す。
応用・総合
問40ファイルIO
読み取り用にファイルを開き、エラーチェック。
FILE *fp = fopen("data.txt", "[1]");
if (fp == [2]) { perror("fopen"); return 1; }
fclose(fp);
[1]: [2]:
答え: r, NULL
問41マクロ
#define SQUARE(x) x * x のとき SQUARE(3+1) の値は?
答え: 7
3+1*3+1 = 7。期待は16。引数を括弧で囲むのが正しい定義。
問42バブルソート
{5, 2, 4, 1, 3} を昇順にバブルソート。外側ループ1パス後の状態。
答え: 2, 4, 1, 3, 5
最大値5が末尾に移動する。
問44const の意味
次のコードがコンパイルエラーになる行番号は?
1: const int x = 10;
2: printf("%d", x);
3: x = 20;
4: printf("%d", x);
行:
答え: 3
const変数は書き換え不可。行3で代入するとエラー。
問45共用体
次の union のサイズ(バイト)は? (int=4, double=8)
union U {
int i;
char c;
double d;
};
sizeof(union U) =
答え: 8
共用体は最大メンバのサイズ。double が最大で 8バイト。