首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言進階測試題精選:16 道考察核心功力的經典題目

     編輯:關於C語言

測試題來源與價值

源自 Steven Kobes 的 C 測試題,專為招聘 C 開發者或自我檢測設計。涵蓋 setjmp/longjmp、結構體記憶體佈局、遞歸、指標算術、運算符優先級、sizeof 語義、函數指標、可變參數、位運算技巧等核心難點。

精選題目深度解析

第 1 題:setjmp/longjmp 非局部跳轉

static jmp_buf buf;
int main() {
    volatile int b = 3;
    if (setjmp(buf) != 0) {
        printf("%d\n", b);  // 輸出 5
        exit(0);
    }
    b = 5;
    longjmp(buf, 1);
}

答案:B (5)。關鍵點:

  • volatile 防止編譯器優化掉 b 的修改
  • 首次 setjmp 返回 0,執行 b=5 後 longjmp 跳回
  • 二次進入 setjmp 返回 longjmp 的值 1,打印當前 b=5
  • 類比遊戲「存檔/讀檔」,常用於異常恢復機制

第 2 題:結構體記憶體佈局與指標轉換

struct node { char a; char b; short c; int d; };
struct node s = {3, 5, 6, 99};
struct node *pt = &s;
printf("%X\n", *(int*)pt);  // 輸出 60503

解析:32 位系統下 char=1B, short=2B, int=4B,結構體自然對齊無填充。pt 強轉為 int* 解引用,讀取前 4 字節:0x03, 0x05, 0x06, 0x00(小端序)組成 0x00060503 = 十六進制 60503。

第 3 題:遞歸快速冪算法

int foo(int x, int n) {
    int val = 1;
    if (n > 0) {
        if (n % 2 == 1) val *= x;
        val *= foo(x * x, n / 2);
    }
    return val;
}

計算 x^n,採用「平方乘」法,遞歸深度 log₂n。紙上推演即可得解。

第 4 題:指向陣列的指標陷阱

int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a + 1);
printf("%d %d\n", *(a+1), *(ptr-1));  // 輸出 2 5

關鍵:&a 類型為 int(*)[5],&a+1 跨越整個陣列(5*sizeof(int)),指向 a[5](越界位置)。強轉為 int* 後步長變為 sizeof(int),ptr-1 指向 a[4] 值 5。

第 5 題:二維陣列指標步長

void foo(int b[][3]) { ++b; b[1][1] = 9; }
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
foo(a);
printf("%d\n", a[2][1]);  // 輸出 9

++b 步長為 3*sizeof(int),指向第二行 {4,5,6}。b[1] 即第三行 {7,8,9},b[1][1] 對應 a[2][1] 被改為 9。

第 6 題:逗號運算符與優先級

c = a, b;  // c = a (賦值優先級 > 逗號)
d = (a, b); // d = b (逗號表達式值為最後一項)

第 7-8 題:二維陣列指標、返回局部指標陷阱

第 7 題同第 5 題原理。第 8 題:f1 返回棧上局部變數地址(未定義行為),f2 解引用未初始化指標(崩潰),f3 malloc 動態分配(正確)。

第 9 題:sizeof 不求值特性

int i = 3, j;
j = sizeof(++i + ++i);  // i 仍為 3, j = sizeof(int) = 4

sizeof 運算元表達式不求值,僅在編譯期推導類型大小。

第 10 題:函數指標陣列與參數傳遞

void (*p[2])(int*, int) 是函數指標陣列。f1 交換 *p 與 q,但 q 為值傳遞,外部 b 不變。輸出 5 3 5 3。

第 11 題:遞歸與前置遞減

e(3) 遞歸調用,前置 --n 先減後用。輸出序列:0 1 0 1 2 1 0。

第 12 題:複雜類型聲明解讀

typedef int (*test)(float*, float*);

test 是「指向函數的指標類型」,該函數接受兩個 float* 返回 int。對照 bsearch、qsort、signal 練習。

第 13-14 題:陣列下標交換律

(buf+1)[5] = *(buf+1+5) = buf[6] = 9。5[buf+1] 同理。利用 a[b] ≡ *(a+b) ≡ b[a] 特性。

第 15 題:可變參數與位計數技巧

i &= i - 1;  // 消除最低位 1,循環次數 = 二進制中 1 的個數
// 7(111) → 6(110) → 4(100) → 0,計數 3

Hacker's Delight 經典技巧,計算 5(101) 和 7(111) 的 1 個數之和 = 2+3=5。

第 16 題:靜態局部變量生命週期

int counter(int i) {
    static int count = 0;  // 僅初始化一次,生命週期贯穿程序
    count += i;
    return count;
}
// main 中累加 0+1+2+3+4+5 = 15

這 16 題覆蓋的核心知識圖譜

領域涉及題目
非局部跳轉/異常處理1
記憶體佈局/對齊/指標轉換2, 4, 5, 7
遞歸/演算法3, 11
運算符優先級/逗號/ sizeof6, 9
函數指標/回調10
未定義行為/棧/堆8
複雜聲明/類型系統12
陣列下標本質13, 14
可變參數/位運算15
存儲類別/生命週期16
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved