題目:int a[10]; 下列哪個表達式**不能**表示 a[1] (第二個元素) 的地址?
A. a + sizeof(int) B. &a[0] + 1 C. (int*)&a + 1 D. (int*)((char*)&a + sizeof(int))
sizeof(int)=4,a 地址為 0x1000)| 選項 | 表達式 | 類型 | 計算過程 | 結果地址 | 是否正確 |
|---|---|---|---|---|---|
| A | a + sizeof(int) | int* | 指針算術:a + 4 → 地址 + 4*4 = +16 字節 | 0x1010 (a[4]) | ❌ 錯誤 |
| B | &a[0] + 1 | int* | 指針算術:&a[0] + 1 → 地址 + 1*4 = +4 字節 | 0x1004 (a[1]) | ✅ 正確 |
| C | (int*)&a + 1 | int* | &a 類型 int(*)[10],+1 → 跳過整個數組 +40 字節 | 0x1028 (a[10] 越界) | ❌ 錯誤 |
| D | (int*)((char*)&a + sizeof(int)) | int* | &a 轉 char* → 字節算術 +4 → 再轉 int* | 0x1004 (a[1]) | ✅ 正確 |
a vs &a:
a 類型 int*,值為首元素地址 (&a[0]),步長 sizeof(int)。&a 類型 int(*)[10] (指向整個數組的指針),值同 a,但步長 sizeof(int[10]) = 40。int* + 1 → +4 字節。char* + 1 → +1 字節。int(*)[10] + 1 → +40 字節。sizeof(int) 是字節數,不可直接加在 int* 上:選項 A 犯了「以字節為單位加在元素指針上」的低級錯誤。char* 做字節級偏移,再轉回目標類型,實現任意字節偏移的通用技法。#includeint main() { int a[10] = {1,2,3,4,5,6,7,8,9,0}; printf("a[1] 地址: %p 值: %d\n", &a[1], a[1]); printf("A: %p 值: %d\n", a + sizeof(int), *(a + sizeof(int))); // a[4] printf("B: %p 值: %d\n", &a[0] + 1, *(&a[0] + 1)); // a[1] ✅ printf("C: %p 值: %d\n", (int*)&a + 1, *((int*)&a + 1)); // a[10] 越界 printf("D: %p 值: %d\n", (int*)((char*)&a + sizeof(int)), *((int*)((char*)&a + sizeof(int)))); // a[1] ✅ return 0; }
選項 A 和 C 都不能表示 a[1] 的地址。若單選最典型錯誤為 **A** (直接用字節數加元素指針)。