統測資電類・資訊科專業科目(二)核心考點

第 6 章:陣列與字串處理

本章統整統測程式設計中「資料集合」的核心工具:一維/二維陣列、C字串的本質、以及陣列與指標密不可分的關係(111~115 年共計 12 題考古真題,是單章題數最多的章節)。 出題老師最愛把「陣列自動補0」、「二維字元陣列重組中文順序」、「指標算術偏移」與「變數遮蔽」揉合在一起設計陷阱。 本教學將帶你掌握清晰的索引推算技巧,並透過12 題真題 + 5 題模擬題的所有選項深度剖析,徹底掃除所有答題盲點!

🧮
7 大核心
陣列與字串觀念全解構
🎯
12 題真題
111~115 統測題全收錄
💡
全選項剖析
A/B/C/D 逐項深入拆解
🚀
100% 互動
點擊即答 + 展開詳解

1 陣列宣告與「未給值的元素自動補0」規則

陣列宣告時,可以只給部分元素的初始值——就像訂了一整排置物櫃(宣告的元素個數),但只把貼紙分配給前幾格(提供的初始值)。沒被分配到貼紙的置物櫃,C 語言會自動幫你貼上「0」,並不是空的、也不是垃圾值。

C Code:宣告個數大於初始值個數,多的自動補0
int arr[4] = {1, 2, 3};      // 元素個數宣告4個,只給3個值
printf("%d", arr[3]);        // 未給值的 arr[3] 自動補0 → 印出 0
🖥️ 終端機執行輸出結果
0
⚠️ 統測常考陷阱:這條規則只在「有給部分初始值」時成立

只要宣告陣列時有用 {...} 提供至少一個初始值,C 語言就會保證剩下沒給值的元素自動補0,這是語言明確保證的行為,不是未定義的垃圾值。統測很喜歡用這條規則設計「陣列宣告4個卻只給3個值,第4個是多少?」這類題目,答案永遠是0,不需要懷疑。

2 C 字串的本質:以 '\0' 結尾的 char 陣列

C 語言沒有專屬的「字串型態」,字串其實就是一個字元陣列,只是多了一個規定:內容的最後必須有一個特殊的空字元 '\0' 當作結束標記。printf 的 %s 就是靠這個標記知道要印到哪裡停下來。

C Code:字元陣列與字串結尾 '\0'
char name[6] = "Alex";       // 字元陣列:'A','l','e','x','\0',(未用)
printf("%s", name);          // 印到 '\0' 為止 → 印出 Alex
💡 白話比喻:'\0' 就像文章的句號

想像 %s 是一個只會「一直往下讀,讀到句號才停」的朗讀機器。陣列裡句號('\0')後面即使還留著沒被清掉的舊資料,也完全不會被讀到、不會被印出來——朗讀機器看到句號就停了。

⚠️ "Alex" 只佔5個位置,但 name 宣告了6個

字串常值 "Alex" 在記憶體裡實際存放的是 'A','l','e','x','\0' 共5個字元(別忘了算上結尾的 '\0'),char name[6] 多留的第6格目前沒被用到(若有給初始值以外的部分,同樣會自動補0)。宣告字元陣列時,記得預留的大小要「字串實際長度 + 1」才夠放結尾的 '\0'。

3 strlen/strcmp:字串內容比較不能用 ==

字串既然是陣列,陣列名稱在大部分情況下會退化成「指向第一個元素的指標」——這代表用 == 比較兩個字串陣列,比的其實是兩塊記憶體的位址是否相同,而不是「內容是否一樣」,幾乎不會是你要的結果。要比較字串內容,要改用標準函式庫的 strcmp();要知道字串長度,要用 strlen()。

C Code:strlen 與 strcmp 的正確用法
#include <stdio.h>
#include <string.h>
int main(void) {
    char a[] = "cat";
    char b[] = "cat";
    printf("strlen(a) = %zu\n", strlen(a));     // 3(不含結尾的'\0')
    printf("strcmp(a,b) = %d\n", strcmp(a, b)); // 0代表兩字串內容相同
    // if (a == b) 是常見錯誤!這樣比較的是兩個陣列的記憶體位址,不是內容
    return 0;
}
🖥️ 終端機執行輸出結果
strlen(a) = 3
strcmp(a,b) = 0
函式作用回傳值的意義
strlen(s)計算字串長度字元個數,不含結尾的 '\0'
strcmp(a,b)比較兩字串「內容」0 代表內容完全相同;非0代表不同
a == b(陣列名稱)比較兩個指標的「位址」幾乎必定是「假」,因為是兩塊不同的記憶體

4 二維陣列與二維字元陣列(中文字串表)的宣告與走訪

二維陣列可以想成「陣列的陣列」,第一個索引是列(row)、第二個是行(column)。統測特別愛用二維字元陣列(如 char S[10][4])存放一組固定長度的中文字串——每個中文字在UTF-8編碼下通常占3 bytes,加上結尾的 '\0' 共4 bytes,剛好對應行的大小。

C Code:二維陣列(矩陣)走訪
int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} };
for (int r = 0; r < 2; r++) {
    for (int c = 0; c < 3; c++)
        printf("%d ", matrix[r][c]);
    printf("\n");
}
C Code:二維字元陣列存放中文字,用索引挑出正確順序
char S[9][4] = {"沖","收","脫","蓋","泡","沖","蓋","脫","送"};
// 索引:0=沖 1=收(干擾) 2=脫 3=蓋(干擾) 4=泡 5=沖(干擾) 6=蓋 7=脫(干擾) 8=送
for (int i = 0; i < 9; i += 2)
    printf("%s", S[i]);
// 只印出偶數索引:沖脫泡蓋送(正確的燒燙傷急救步驟)
⚠️ 統測愛考題型:用一組「索引清單」重組出正確順序

統測常把一組資料(例如急救步驟、密語)故意打亂順序、中間穿插干擾字,存進二維字元陣列裡,再考你「該用哪一組索引,才能依序組出正確的內容」。解題訣竅:先把陣列每個索引對應的內容抄下來列成清單,再逐一比對每個選項給的索引順序,實際模擬一次印出結果,不要用猜的。

5 陣列名稱退化成指標/*(p+i) 與 p[i] 的等價關係

陣列名稱在大部分運算情境下,會自動「退化」成一個指向第一個元素的指標。這代表 p[i] 與 *(p+i) 其實是完全等價的兩種寫法——只是換一種方式表達「往後跳 i 格,再把那格的值取出來」。

C Code:陣列、指標、*(p+i)、p[i] 四種寫法互通
int arr[3] = {100, 200, 300};
int *p = arr;              // 陣列名稱會自動退化成指向第一個元素的指標
printf("%d\n", *p);        // 100
printf("%d\n", *(p + 1));  // 200,指標+1會依型態大小跳過一個int
printf("%d\n", p[2]);      // 300,p[i]其實就是*(p+i)的另一種寫法
寫法意義等價寫法
*pp目前指向位置的值p[0]
*(p+1)p往後跳1格,取該格的值p[1]
p[i]p往後跳i格,取該格的值*(p+i)
🧠 陣列指標運算的兩個常考延伸

1. 若 pData = &Data[2],則 *(pData+3) 指向的其實是 Data[2+3] = Data[5]——起始點會跟著指標當初指向的位置一起偏移,不是直接從 Data[3] 算起。
2. *n(n是陣列名稱)永遠等同於 n[0],是「陣列第一個元素」的另一種寫法,不是在對整個陣列做什麼特殊操作。

6 陣列+指標混合運算的常見陷阱

當陣列與指標混在一起、又加上變數遮蔽(shadowing)時,追蹤程式的難度會大幅提升。這裡整理兩個統測最愛的複合陷阱:

C Code:區域陣列遮蔽了同名的全域指標
char *ptr = "Outside";        // 全域指標
int main(void) {
    char str[20] = "This is a book";
    char ptr[20] = "Main";        // 區域「陣列」,跟全域指標同名!
    *ptr = *str;                  // 只改了ptr[0]這一個字元
    printf("%s", ptr);
    return 0;
}
⚠️ 陷阱一:同名的「區域陣列」會遮蔽「全域指標」

main() 內重新宣告了一個同名的區域變數 ptr(這次是陣列,不是指標),這個區域 ptr 會遮蔽外層的全域指標 ptr。函式內所有用到 ptr 的地方,指的都是這個區域陣列 "Main",跟全域的 "Outside" 完全無關。

⚠️ 陷阱二:*ptr = *str 只改「一個字元」,不是整個字串

* 解參考一次只能存取、賦值一個字元。*ptr = *str 的意思是「把 str 的第一個字元,指定給 ptr 的第一個字元」,也就是 ptr[0] = str[0]。這裡把 ptr 原本的 'M' 換成了 str 的 'T',其餘字元(a, i, n)完全不受影響,結果是 "Tain",並不是把整個字串複製過去(那要用 strcpy())。

7 字元陣列的 ASCII 算術與陣列+迴圈的綜合追蹤

字元(char)在底層其實就是一個整數(ASCII碼),所以字元可以直接做加減運算——'x' + 1 會得到 ASCII 碼比 'x' 大1的下一個字元。這個技巧常跟迴圈、陣列自動補0混在一起出題。

C Code:陣列與字元陣列同步用迴圈遞增
int used[6] = {1, 2, 3, 4}, i;   // used[4]、used[5] 自動補0
char name[6] = "Alex";           // A,l,e,x,'\0'
for (i = 1; i < 4; i++) {
    used[i] = used[i] + 1;
    name[i] = name[i] + 1;       // 字元的ASCII碼加1,變成下一個字元
}
// name[3] 原為 'x',加1後是 ASCII 碼比 'x' 大1的字元 'y'
💡 常見 ASCII 順位(大寫、小寫字母、數字皆連續遞增)

'A'~'Z'、'a'~'z'、'0'~'9' 這三組字元在 ASCII 表裡都是連續遞增排列的,所以 字元 + 1 一定會得到「字母順序上的下一個」字元(例如 'x'+1='y'、'A'+1='B'),但要小心:'z'+1 並不會神奇地繞回 'a',而是繼續往下一個 ASCII 碼(超出小寫字母範圍的符號),除非程式有額外寫繞回的邏輯。

🧠 追蹤這類題目的訣竅:把每個索引位置的「初始值」與「最終值」分開列表

遇到「陣列+迴圈+ASCII算術」綜合題,先把每個索引位置迴圈開始前的值列一欄,再把迴圈跑完後的值列另一欄,逐一核對哪些索引真的被迴圈的範圍(例如 i<4)覆蓋到、哪些沒有,才不會誤把初始值當成最終答案。

8 111~115 歷屆統測真題全選項深度剖析(共 12 題)

以下收錄統測專業科目(二)近年全部 12 題陣列與字串處理真題。每題均提供高解析度原始考題掃描圖、互動選項按鈕與所有選項逐項深入解析:

111 統測專二 Q45 📌 概念:陣列自動補0/迴圈累加追蹤
試題來源:技專校院入學測驗中心
下列 C 語言程式碼執行後,變數 Sum 的值為何?
題幹程式碼
#include <stdio.h>
int main()
{
    int Sum=0, Array[4]={1, 2, 3}, i;
    for(i=1; i<4; i++)
        Sum+=Array[i];
    printf("%d", Sum);
    return 0;
}
111 統測專二 Q45 題目截圖
本題標準答案: (C) 5

🔍 四個選項逐項深度剖析

選項 A(3)錯誤解析
此答案很可能只把迴圈想成執行了一輪,誤以為 Sum 只單純等於 Array[2] 的值3,忽略了迴圈其實會執行三輪(i=1,2,3),要把三個元素的值依序累加起來,而不是只取其中一個元素的值。
選項 B(4)錯誤解析
此答案可能誤以為 Array[3] 沒有被明確給值,代表它的值是「不確定的」,於是隨意估算了一個較小的殘留值來計算 Sum。但 C 語言有明確規則:陣列宣告的元素個數(4)大於給定初始值的個數(3)時,剩餘未給值的元素會被自動補0,Array[3] 確實就是0,不是任何隨機殘留值。
正確答案完整推導(★ 本題標準答案)
Array 宣告4個元素但只給3個初始值,Array[3] 依規則自動補0,陣列實際內容為 {1,2,3,0}。迴圈 i 從1跑到3:Sum+=Array[1](2)→2;Sum+=Array[2](3)→5;Sum+=Array[3](0)→5。最終 Sum=5,選 (C)。
選項 D(6)錯誤解析
此答案很可能誤以為迴圈執行範圍是 i=0 到 i<3(也就是i=0,1,2),把索引整個往前平移了一格,於是加總了 Array[0]+Array[1]+Array[2]=1+2+3=6,而不是程式碼實際寫的 i=1 到 i<4(i=1,2,3),漏看了迴圈其實是從索引1開始,不是0。
111 統測專二 Q46 📌 概念:指標與字串/前置遞增對指標的影響
試題來源:技專校院入學測驗中心
下列 C 語言程式碼執行後,輸出為何?
題幹程式碼
#include <stdio.h>
int main()
{
    char Str[]="abcde";
    char *ptr=Str;
    printf("%s", ++ptr);
    return 0;
}
111 統測專二 Q46 題目截圖
本題標準答案: (D) bcde

🔍 四個選項逐項深度剖析

選項 A(a)錯誤解析
此答案誤以為 %s 只會印出指標目前指向的「單一字元」,而不是從該位置開始一路印到字串結尾的 '\0' 為止。%s 是逐一輸出字元直到遇到 '\0',並非只印一個字元,而且也沒有正確算出 ++ptr 之後指向的其實不是原本的 'a'。
選項 B(b)錯誤解析
此答案正確算出了 ++ptr 之後指標指向的字元是 'b'(這部分邏輯正確),卻仍然誤解了 %s 的行為——%s 會從指標當下位置開始,一路印到 '\0' 為止,並不是只印出那一個字元。
選項 C(abcde)錯誤解析
此答案誤以為 ++ptr 沒有真正生效,或誤看成後置遞增 ptr++(後置遞增雖然也會移動指標,但整個運算式本身的「值」用的是移動前的舊位址),以為 printf 印的時候 ptr 還停留在原本指向 Str[0] 的位置。但程式碼寫的是前置遞增 ++ptr,會先讓 ptr 真正移動到 Str[1],才把這個「已經移動後」的位址傳給 printf。
正確答案完整推導(★ 本題標準答案)
ptr 原本指向 Str[0]('a')。前置遞增 ++ptr 先讓 ptr 移向 Str[1]('b'),才把這個新位址傳給 printf。%s 從該位址開始輸出,直到遇到 '\0' 為止,故輸出 "bcde",選 (D)。
112 統測專二 Q47 📌 概念:陣列索引+遞增步伐(跑馬燈解碼)
試題來源:技專校院入學測驗中心
跑馬燈設計中,程式執行完後 ShowMessage 字串為 "ILoveTaiwan",則 Count 的初始值應為下列哪一個?
題幹程式碼
const int Count = ? ;
char Dictionary[50] = "IWhLoaorevYTeouTW5aM7iynwyuaTYn?";
char ShowMessage[12] ={0};
char *P = &Dictionary[0];
int Index = 0, Search = 0;
for(Index =0; Index < 11 ; Index++)
{
    ShowMessage[Index] = P[Search];
    Search += Count;
}
112 統測專二 Q47 題目截圖
本題標準答案: (D) 3

🔍 四個選項逐項深度剖析

選項 A(Count=0)錯誤解析
若 Count=0,Search 每輪都會維持0、永遠不變,代表 Index 從0跑到10這11輪,取出的字元全部都是 Dictionary[0],也就是重複印出11次 'I'("IIIIIIIIIII"),與目標字串 "ILoveTaiwan" 完全不符,說明 Count 絕不能是0(沒有真正跳躍讀取不同位置)。
選項 B(Count=1)錯誤解析
若 Count=1,Search 依序為0,1,2,...,10,等於逐字元照原始順序讀取 Dictionary 的前11個字元 "IWhLoaorevY",這只是把 Dictionary 開頭一小段原封不動抄出來,並沒有跳過任何刻意穿插的干擾字元,得不到正確的 "ILoveTaiwan"。
選項 C(Count=2)錯誤解析
若 Count=2,Search 依序為0,2,4,...,20,取出的字元依序是 I,h,o,o,e,Y,e,o,W,a,7,串起來是 "IhooeYeoWa7",跳躍幅度還不夠大,取到的字元仍然大多是 Dictionary 中刻意穿插的干擾字元,並非正確答案。
正確答案完整推導(★ 本題標準答案)
若 Count=3,Search 依序為0,3,6,9,12,15,18,21,24,27,30(共11個位置,對應 Index=0~10)。對照 Dictionary 逐一取出這些位置的字元:I,L,o,v,e,T,a,i,w,a,n,串接起來恰好是 "ILoveTaiwan",與題目要求完全相符,選 (D)。
113 統測專二 Q35 📌 概念:二維字元陣列(中文字串表)索引挑選順序
試題來源:技專校院入學測驗中心
小燕想依燒燙傷急救步驟順序輸出文字,Select[5] 內的 ? 值為下列何者?
題幹程式碼
int TotalSteps = 5;
int Count = 0;
char StepName[9][4] = { "拖","脫","送","沖","蓋","泡","送" };
int Select[5] = {?};
for (Count = 0; Count < TotalSteps; Count+=1)
{
    std::cout << StepName[Select[Count]];
}
113 統測專二 Q35 題目截圖
本題標準答案: (C) 3,1,5,4,6

🔍 四個選項逐項深度剖析

選項 A(4,2,5,6,3)錯誤解析
代入索引:StepName[4]="蓋"、[2]="送"、[5]="泡"、[6]="送"、[3]="沖",依序印出「蓋送泡送沖」,順序完全打亂,並不是正確的燒燙傷急救步驟「沖脫泡蓋送」。
選項 B(4,1,6,5,7)錯誤解析
代入索引:StepName[4]="蓋"、[1]="脫"、[6]="送"、[5]="泡"、[7](陣列只給了7個初始值,索引7未給值,是空字串),依序印出「蓋脫送泡」加上空字串,不僅順序錯誤,還用到了未初始化的索引位置。
正確答案完整推導(★ 本題標準答案)
StepName 索引依序為:0=拖, 1=脫, 2=送, 3=沖, 4=蓋, 5=泡, 6=送(索引7、8未給值,是空字串)。正確急救步驟為「沖、脫、泡、蓋、送」,對應索引依序是3(沖)、1(脫)、5(泡)、4(蓋)、6(送,用第二個「送」的位置),選 (C)。
選項 D(3,1,4,5,2)錯誤解析
代入索引:StepName[3]="沖"、[1]="脫"、[4]="蓋"、[5]="泡"、[2]="送",依序印出「沖脫蓋泡送」——跟正確答案非常接近,但「蓋」與「泡」的先後順序被對調了,正確順序應該是「泡」在「蓋」之前。
113 統測專二 Q38 📌 概念:指標算術/陣列自動補0/敘述真假判讀
試題來源:技專校院入學測驗中心
有關宣告陣列與指標的片段程式,下列敘述何者正確?
題幹程式碼
int  Data[10] = {1,2,3,4,11,12,13,15};
int  *pData = &Data[2];
113 統測專二 Q38 題目截圖
本題標準答案: (B) if(*(pData + 3) == Data[5]) 判斷式結果為真

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
pData 指向 &Data[2],所以 pData[1] 等同於 *(pData+1) = Data[2+1] = Data[3] = 4,並不等於1。pData[1]==1 這個判斷式實際上是「假」,但選項卻宣稱它是「真」,敘述錯誤。
正確答案完整推導(★ 本題標準答案)
由於 pData 指向 Data[2],pData+3 正好指向 Data[2+3]=Data[5],所以 *(pData+3) 本質上就是在比較「Data[5] 跟它自己」,結構上恆為真(不管 Data[5] 實際存的是什麼值都一樣),敘述正確,選 (B)。
選項 C 錯誤解析
Data 陣列只給了8個初始值(索引0~7),索引8、9未給值,依規則自動補0,所以 Data[9] 確實等於0,Data[9]==0 這個判斷式實際上是「真」,但選項卻宣稱它是「假」,敘述錯誤。
選項 D 錯誤解析
pData[5]=*(pData+5)=Data[2+5]=Data[7]=15;*(pData+2)=Data[2+2]=Data[4]=11;兩者相減 15-11=4,剛好等於 Data[3]=4,所以 Data[3]==(pData[5]-*(pData+2)) 這個判斷式實際上是「真」,但選項卻宣稱它是「假」,敘述錯誤。
114 統測專二 Q35 📌 概念:陣列元素交換(swap)重組順序
試題來源:技專校院入學測驗中心
程式行號13~15應置入哪個選項,才能輸出正確的燒燙傷急救步驟順序?
題幹程式碼
char StepName[5][4] = {"脫","蓋","送","沖","泡"};
void swap(char *a, char *b) {
    char tmp;
    for (x = 0; x < 3; x++) {
        tmp = a[x];
        a[x] = b[x];
        b[x] = tmp;
    }
}
int main(void) {
    /* 行號13~15待填 */
    for (i = 0; i<5 ;i++)
        printf("%s", StepName[i]);
    return 0;
}
114 統測專二 Q35 題目截圖
本題標準答案: (B) swap(StepName[0],StepName[3]); swap(StepName[3],StepName[1]); swap(StepName[2],StepName[4]);

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
初始陣列(索引0~4)=脫,蓋,送,沖,泡。實際模擬:swap(1,3)→[脫,沖,送,蓋,泡];swap(2,1)→[脫,送,沖,蓋,泡];swap(3,4)→[脫,送,沖,泡,蓋]。結果為「脫送沖泡蓋」,並不是正確的「沖脫泡蓋送」。
正確答案完整推導(★ 本題標準答案)
初始陣列(索引0~4)=脫,蓋,送,沖,泡。實際模擬:swap(0,3)交換索引0與3→[沖,蓋,送,脫,泡];swap(3,1)交換索引3與1→[沖,脫,送,蓋,泡];swap(2,4)交換索引2與4→[沖,脫,泡,蓋,送]。結果恰為「沖脫泡蓋送」,與正確的急救步驟完全相符,選 (B)。
選項 C 錯誤解析
實際模擬:swap(1,3)→[脫,沖,送,蓋,泡];swap(2,1)→[脫,送,沖,蓋,泡];swap(4,4)是讓元素跟自己交換,結果不會改變,仍是[脫,送,沖,蓋,泡]。結果為「脫送沖蓋泡」,並不是正確的「沖脫泡蓋送」。
選項 D 錯誤解析
前兩步 swap(0,3)、swap(3,1) 跟正確答案(B)相同,會得到 [沖,脫,送,蓋,泡],但第三步 swap(StepName[2],StepName[5]) 中的索引5超出了陣列範圍(StepName 只宣告了5個元素,有效索引是0~4),這是存取未定義記憶體的危險寫法,並不能得到正確、安全的結果。
114 統測專二 Q36 📌 概念:指標與字串/區域變數遮蔽全域變數
試題來源:技專校院入學測驗中心
曉華想了解字元、字串和指標的關係,程式輸出結果為何?
題幹程式碼
char *ptr="Outside";
int main()
{
    char str[20]="This is a book\0";
    char ptr[20]="Main\0";
    *ptr = *str;
    printf("%s", ptr);
    return 0;
}
114 統測專二 Q36 題目截圖
本題標準答案: (D) Tain

🔍 四個選項逐項深度剖析

選項 A(Outside)錯誤解析
此答案誤以為程式最終用的是全域指標 char *ptr="Outside",忽略了 main() 內部用 char ptr[20]="Main" 重新宣告了一個同名的區域陣列,這個區域 ptr 會遮蔽外層的全域指標,函式內所有的 ptr 都是指這個區域陣列,不可能是 "Outside"。
選項 B(Mhis)錯誤解析
此答案把 *ptr = *str 的賦值方向弄反了,誤以為是把 ptr 的第一個字元 'M' 指定給 str(讓 str 的 'T' 被 'M' 取代變成 "Mhis...")。但程式碼寫的其實是「把 str 的第一個字元指定給 ptr」,被改變的是 ptr,不是 str。
選項 C(This is a book)錯誤解析
此答案誤以為 *ptr = *str 會把整個 str 字串內容整個複製給 ptr(就像呼叫了 strcpy() 一樣),但 * 解參考一次只能存取、賦值「一個字元」,這行只把 ptr 的第一個字元換成了 str 的第一個字元,並沒有複製整個字串。
正確答案完整推導(★ 本題標準答案)
main() 內的區域陣列 char ptr[20] 遮蔽了全域指標 char *ptr,故程式中所有的 ptr 皆指向區域陣列 "Main"。*ptr = *str 只是把 str 第一個字元 'T' 指定給 ptr[0],把原本的 'M' 換成 'T',其餘字元(a, i, n)不變,ptr 變成 "Tain",選 (D)。
114 統測專二 Q42 📌 概念:字串比對/巢狀迴圈追蹤/sizeof 與計數變數重設
試題來源:技專校院入學測驗中心
程式用來逐字比對字串 str 中是否有字串 query 指定的字串,變數 len、ans 和 match_count 最終值分別為何?
題幹程式碼
char str[100] = "This is a book and that is a dog.\0";
char ans = 0, match_count=0;
char query[]="is";
int len = sizeof(query), i , j;
for(i=0; (i<100-len)&&(str[i]!='\0'); i++){
    for(j=0; j<len-1; j++)
        if(query[j]==str[i+j])
            ans++;
        else
            break;
    if(ans==len-1)
        printf("%d-th match str[%d] !\n", ++match_count, i);
    ans=0;
}
printf("%d, %d, %d", len, ans, match_count);
114 統測專二 Q42 題目截圖
本題標準答案: (B) 3, 0, 3

🔍 四個選項逐項深度剖析

選項 A(3, 0, 0)錯誤解析
len 與 ans 都算對了,但 match_count 算錯了。此答案可能誤判內層比對邏輯完全沒有真的抓到任何一次 "is" 子字串,但字串 "This is a book and that is a dog." 裡其實有3處連續出現 'i','s'("This"裡的is、獨立單字"is"、"that is"裡的is),match_count 應該累加到3,不是0。
正確答案完整推導(★ 本題標準答案)
sizeof(query) 是對字元陣列(含結尾 '\0')取大小,query 是 "is\0" 共3個bytes,故 len 固定為3,且完全不會隨比對過程改變。字串中出現連續 'i','s' 的位置有3處("This"裡、獨立單字"is"、"that is"裡),match_count 累加到3。外層迴圈每一輪結尾都會執行 ans=0;,所以不管中間怎麼變化,最終 ans 恆為0。輸出 "3, 0, 3",選 (B)。
選項 C(0, 3, 0)錯誤解析
len=0 是把 sizeof() 誤看成了 strlen()——sizeof(query) 算的是字元陣列配置的位元組數(含結尾 '\0'),固定是3,不會是0。ans=3 則是誤以為 ans 在比對到相符字串後不會被重置,忽略了外層迴圈每輪結尾都會執行 ans=0;,把 ans(單輪暫存用的計數器)跟 match_count(真正的總計數器)的用途搞混了。
選項 D(2, 0, 3)錯誤解析
ans 與 match_count 都算對了,但 len 算錯了。此答案可能誤以為 sizeof(query) 不包含字串結尾的 '\0',只算 "i" 和 "s" 兩個字元得到2,但 sizeof 對字元陣列而言,算的是配置的「所有」位元組數,包括結尾用來標記字串結束的空字元,所以是3,不是2(若要不含 '\0' 的字元個數,應該用 strlen())。
114 統測專二 Q44 📌 概念:陣列與指標/*(n+i) 與 n[i] 的等價輸出追蹤
試題來源:技專校院入學測驗中心
下列 C 語言程式碼,其執行後輸出結果為何?
題幹程式碼
int n[5]={1, 2, 3, 4, 5}, i;
n[1]=100;
*n = 1;
for(i=0; i<5; i++)
    printf("%d", *(n+i));
114 統測專二 Q44 題目截圖
本題標準答案: (B) 1100345

🔍 四個選項逐項深度剖析

選項 A(12345)錯誤解析
此答案誤以為 n[1]=100; 與 *n=1; 這兩行賦值敘述沒有真的生效,以為陣列從頭到尾都維持初始化時的 {1,2,3,4,5},忽略了這兩行都是會確實修改陣列內容的敘述——第一行把 n[1] 改成100,第二行把 n[0](也就是 *n)設為1(剛好跟原值相同,看起來沒變化)。
正確答案完整推導(★ 本題標準答案)
n[1]=100; 後陣列變為 {1,100,3,4,5};*n 即 n[0],設定為1(值不變,因為原本就是1)。以 *(n+i)(等同 n[i])依序輸出各元素的值 "1","100","3","4","5",直接串接成 "1100345",選 (B)。
選項 C(1210045)錯誤解析
這個答案的數字排列順序被打亂了(100 被拆開穿插到其他數字之間)。可能是在把每輪 *(n+i) 印出的數字依序串接成字串時,中途弄錯了串接順序,而不是把每一輪的完整輸出值依序、原封不動地接在後面。
選項 D(1234100)錯誤解析
這個答案把100放到了字串最後面,且中間用的是 n[1] 被修改前的舊值2(1,2,3,4),可能是誤以為迴圈先照原始陣列 {1,2,3,4,5} 的順序印出前四個值,最後才想起 n[1] 被改成了100,卻誤植到了最後一個位置,而不是在 i=1 那一輪、正確的第二個輸出位置就印出100。
115 統測專二 Q37 📌 概念:陣列/位元權值換算/for 迴圈終止時的計數器值
試題來源:技專校院入學測驗中心
程式統計2個二進位數的位元差異,並轉換成十進位數。程式執行到行號13時,下列何者正確?
題幹程式碼
short i;
unsigned char count = 0, X = 0, Y = 0;
unsigned char x[8]= {1,1,1,1,1,1,1,0};
unsigned char y[8]= {0,1,1,1,1,1,1,1};
for(i = 7; i >= 0; i--){
  if(x[i] != y[i])
    count++;
  X += x[i]*pow(2,7-i); //pow(a,b)傳回a的b次方值
  Y += y[i]*pow(2,7-i);
}
115 統測專二 Q37 題目截圖
本題標準答案: (D) Y=127

🔍 四個選項逐項深度剖析

選項 A(i=0)錯誤解析
此答案誤以為迴圈結束時 i 會停在0,但迴圈是 for(i=7;i>=0;i--),當 i 遞減到0時本體仍會執行(0>=0成立),執行完後還會再執行一次 i-- 讓 i 變成-1,直到 -1>=0 不成立才真正跳出迴圈,因此執行到行號13時 i 其實已經是-1,並不是還停留在0。
選項 B(i=1)錯誤解析
同樣誤判了迴圈結束時 i 的值,可能誤以為迴圈會在 i 即將變成負數「之前」就提早結束。但 C 語言的 for 迴圈條件是在每一輪本體執行前才檢查,i 必須真的遞減到讓 i>=0 不成立(也就是 i=-1)才會停止,不會停在 i=1。
選項 C(X=127)錯誤解析
此答案把 X 和 Y 兩個變數的最終值算反了。逐位元帶入權值計算:X = x[0]×128+x[1]×64+x[2]×32+x[3]×16+x[4]×8+x[5]×4+x[6]×2+x[7]×1 = 128+64+32+16+8+4+2+0 = 254,並不是127;127其實是 Y 的最終值,這個選項把兩個變數的答案對調了。
正確答案完整推導(★ 本題標準答案)
逐位元帶入權值計算 Y:Y = y[0]×128+y[1]×64+y[2]×32+y[3]×16+y[4]×8+y[5]×4+y[6]×2+y[7]×1 = 0+64+32+16+8+4+2+1 = 127,選 (D)。
115 統測專二 Q38 📌 概念:位元差異計數/printf 精度控制 %.3f
試題來源:技專校院入學測驗中心
(承上題,程式碼相同)程式執行後的輸出結果為何?
題幹程式碼(與上題相同)
short i;
unsigned char count = 0, X = 0, Y = 0;
unsigned char x[8]= {1,1,1,1,1,1,1,0};
unsigned char y[8]= {0,1,1,1,1,1,1,1};
for(i = 7; i >= 0; i--){
  if(x[i] != y[i])
    count++;
  X += x[i]*pow(2,7-i);
  Y += y[i]*pow(2,7-i);
}
printf("%.3f", (float)count/8);
115 統測專二 Q38 題目截圖
本題標準答案: (C) 0.250

🔍 四個選項逐項深度剖析

選項 A(00.25)錯誤解析
此答案誤以為 %.3f 的意思是「小數點前後總共固定輸出3位數字」,因而在整數部份前面多補了一個0。但 .3f 規定的其實是「小數點後固定輸出3位」,跟整數部份要印幾位完全無關,也不會在整數部份多補0。
選項 B(0.25)錯誤解析
此答案誤以為 %.3f 會跟一般沒有指定精度的浮點數輸出一樣,只印出「剛好夠表示這個數值」的位數(0.25只需要兩位小數就能精確表示)。但 .3f 是明確要求小數點後固定輸出3位,即使第三位是0也一定要補上,應該是0.250,不是0.25。
正確答案完整推導(★ 本題標準答案)
由上一題分析可知,x 與 y 只在索引0與索引7處不同、其餘6個位置都相同,故 count=2。(float)count/8 = 2/8 = 0.25。%.3f 表示小數點後固定輸出3位,0.25補齊三位小數就是0.250,選 (C)。
選項 D(00.250)錯誤解析
此答案正確算出了小數點後三位是 "250",但誤以為 %.3f 也會像某些「補零到固定寬度」的格式化語法一樣,連整數部份也補一個0。事實上 %.3f 只規定小數點後的位數,並沒有規定整數部份要補零到幾位,0.25的整數部份就只有一位數 "0",不會多印一個0。
115 統測專二 Q45 📌 概念:陣列與字元運算(ASCII加法)/迴圈範圍追蹤
試題來源:技專校院入學測驗中心
下列 C/C++ 語言程式片段執行後的陣列內容,何者正確?
題幹程式碼
int  used[6] = {1, 2, 3, 4}, i;
char name[6] = "Alex";
for(i = 1; i < 4; i++){
    used[i] = used[i] + 1;
    name[i] = name[i] + 1;
}
115 統測專二 Q45 題目截圖
本題標準答案: (B) name[3]='y'

🔍 四個選項逐項深度剖析

選項 A(name[1]='B')錯誤解析
name[1] 原本是字元 'l'("Alex" 的第二個字母),迴圈執行到 i=1 時 name[1]=name[1]+1 會把 'l' 的 ASCII 碼加1,變成 'm',並不是 'B'。'B' 其實是把 name[0]('A')加1才會得到的結果,這個選項可能把索引1誤看成了索引0。
正確答案完整推導(★ 本題標準答案)
name[3] 原本是字元 'x'("Alex" 的最後一個字母),迴圈執行到 i=3 時 name[3]=name[3]+1,把 'x' 的 ASCII 碼加1,得到 ASCII 順序上的下一個字母 'y',選 (B)。
選項 C(used[1]=2)錯誤解析
used[1] 的初始值確實是2,但迴圈明明白白執行了 used[1]=used[1]+1 這一行,把 used[1] 從2變成3。這個選項似乎誤以為迴圈完全沒有真正修改 used 陣列(把初始值直接當成最終值),忽略了迴圈本體確實會執行加1的動作。
選項 D(used[3]=4)錯誤解析
同樣的誤解,used[3] 的初始值是4,但迴圈執行 used[3]=used[3]+1 後,最終值應該是5,這個選項把初始值誤當成了最終值,忽略了迴圈本體對 used[3] 也確實執行了加1的動作(i=1,2,3三輪都會執行到,used[3]對應i=3那一輪)。

9 高職段考與模擬精選實戰題(5 題全選項解析)

透過以下 5 題精選模擬試題,全面檢驗你對陣列補0、字串函式、二維陣列索引與指標算術的掌握度:

模擬實戰第 1 題 📌 概念:陣列自動補0與迴圈累加
已知下列 C 語言程式碼片段,執行後印出的 sum 值為何?
C Code
int arr[5] = {10, 20};
int i, sum = 0;
for (i = 0; i < 5; i++)
    sum += arr[i];
printf("%d", sum);
本題標準答案: (A) 30

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
陣列宣告5個元素但只給2個初始值,未給值的 arr[2]、arr[3]、arr[4] 依規則自動補0,陣列實際內容為 {10,20,0,0,0}。迴圈跑滿5輪,加總 10+20+0+0+0=30,選 (A)。
選項 B(10)錯誤解析
此答案可能誤以為迴圈只加總了「真正給了初始值」的元素,忽略了迴圈條件是 i<5,會確實跑滿5輪,把所有5個元素(含自動補0的那些)都加總進去,並不是只挑選有給初始值的元素。
選項 C(-1)錯誤解析
此答案誤以為未給初始值的陣列元素會是不確定的「垃圾值」甚至負數,讓加總結果出現異常。但只要陣列宣告時「有」提供部分初始值(即使只給1個或幾個),C 語言就保證其餘未給值的元素一律自動補0,並不是垃圾值——這點只有在完全沒有初始化陣列時才不成立。
選項 D 錯誤解析
陣列宣告的元素個數(5)大於給定初始值的個數(2)是完全合法的語法,不會產生編譯錯誤或警告,這是 C 語言陣列初始化的正常用法。
模擬實戰第 2 題 📌 概念:strcmp/strlen 的正確用法
已知下列 C 語言程式碼片段,執行後的輸出結果為何?
C Code
#include <stdio.h>
#include <string.h>
int main(void) {
    char a[] = "hello";
    char b[] = "help";
    if (strcmp(a, b) == 0)
        printf("相同");
    else
        printf("不同,strlen(a)=%zu", strlen(a));
    return 0;
}
本題標準答案: (B) 不同,strlen(a)=5

🔍 四個選項逐項深度剖析

選項 A 錯誤解析
此答案誤以為 strcmp(a,b) 是在比較兩字串「開頭幾個字元是否相同」,"hello" 與 "help" 確實開頭三個字元都是 "hel",但 strcmp 比較的是整個字串內容是否完全一致,兩者從第4個字元開始就不同('l' 對 'p'),strcmp 的回傳值不會是0,代表字串內容不同,應該走 else 分支。
正確答案完整推導(★ 本題標準答案)
strcmp(a,b) 比較的是字串 "hello" 與 "help" 的完整內容,兩者不同,回傳值不為0,故執行 else 分支。strlen(a) 計算的是字串 a("hello")的字元長度,不含結尾的 '\0',共5個字元,故印出 "不同,strlen(a)=5",選 (B)。
選項 C(strlen(a)=6)錯誤解析
此答案誤以為 strlen() 會把字串結尾的 '\0' 也算進長度裡——"hello" 含 '\0' 確實共佔用6個bytes的記憶體空間沒錯,但 strlen() 回傳的是「不含結尾 '\0'」的字元個數,也就是5,不是6。這是把 strlen() 跟陣列實際佔用的記憶體大小(可用 sizeof 取得)搞混了。
選項 D(strlen(a)=4)錯誤解析
可能誤數了 "hello" 的字母個數(h-e-l-l-o 共5個字母,不是4個),這是單純的計算失誤,"hello" 確實有5個字元。
模擬實戰第 3 題 📌 概念:二維字元陣列(中文字串表)索引挑選
已知下列 C 語言程式碼片段,執行後印出的內容為何?
C Code
char Item[8][4] = {"筆","尺","橡皮擦","剪刀","膠水","釘書機"};
int Order[3] = {2, 4, 0};
for (int i = 0; i < 3; i++)
    printf("%s", Item[Order[i]]);
本題標準答案: (A) 橡皮擦膠水筆

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
Item 索引依序為:0=筆, 1=尺, 2=橡皮擦, 3=剪刀, 4=膠水, 5=釘書機。Order[0]=2 → Item[2]="橡皮擦";Order[1]=4 → Item[4]="膠水";Order[2]=0 → Item[0]="筆"。依序印出 "橡皮擦膠水筆",選 (A)。
選項 B(筆膠水橡皮擦)錯誤解析
此答案把順序整個反過來印了,可能誤以為迴圈是從 Order 陣列的最後一個索引往前印,但程式碼寫的 for(i=0;i<3;i++) 明明白白是從 Order[0] 開始、依序往後印到 Order[2],順序不會顛倒。
選項 C(尺剪刀筆)錯誤解析
此答案很可能把 Order 陣列裡的索引值「2,4,0」誤看成了「1,3,0」(各自少算了1),對應到 Item[1]="尺"、Item[3]="剪刀"、Item[0]="筆",是索引判讀上的偏移錯誤。
選項 D(橡皮擦釘書機筆)錯誤解析
第一與第三個字對了(橡皮擦、筆),但中間的字錯了——把 Order[1]=4 誤看成了5,對應到 Item[5]="釘書機" 而非正確的 Item[4]="膠水",是單一索引值看錯的失誤。
模擬實戰第 4 題 📌 概念:指標算術與 *(p+i)、p[i] 的等價運算
已知下列 C 語言程式碼片段,執行後印出的內容為何?
C Code
int data[4] = {7, 14, 21, 28};
int *p = data;
printf("%d %d %d", *(p+2), p[1], *p);
本題標準答案: (A) 21 14 7

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
*(p+2) 等同於 data[2]=21;p[1] 是 *(p+1) 的另一種寫法,等同於 data[1]=14;*p 等同於 data[0]=7。依 printf 引數順序印出 "21 14 7",選 (A)。
選項 B(7 14 21)錯誤解析
這個答案把三個數字的順序整個反過來了,可能是把三個運算式的先後順序搞混。printf 的引數順序是 *(p+2), p[1], *p,必須照這個順序輸出,不能自行對調成由小到大排列。
選項 C(28 14 7)錯誤解析
把 *(p+2) 誤算成了 data[3]=28(多加了1個索引),可能是把指標算術「+2」誤想成「移動到陣列的第2個之後那格」,而非「移動到索引為2的那格」。正確的 *(p+2) 就是 data[2],索引直接對應加的數字,不需要再多加1。
選項 D(21 1 7)錯誤解析
把 p[1] 誤算成了1,可能是把 p[1] 誤讀成「指標p本身加1的結果」(也就是位址的偏移量本身),而不是「p[1]是*(p+1)的另一種寫法,代表陣列索引1位置存放的值」。p[1] 應該等於 data[1]=14,不是1。
模擬實戰第 5 題 📌 概念:陣列自動補0+ASCII算術綜合追蹤
已知下列 C 語言程式碼片段,執行後印出的內容為何?
C Code
int score[5] = {60, 75};
char grade[5] = "ABCDE";
int i;
for (i = 1; i < 3; i++) {
    score[i] = score[i] + 10;
    grade[i] = grade[i] + 1;
}
printf("score[2]=%d, grade[2]=%c", score[2], grade[2]);
本題標準答案: (A) score[2]=10, grade[2]=D

🔍 四個選項逐項深度剖析

正確答案完整推導(★ 本題標準答案)
score 陣列宣告5個元素但只給2個初始值,score[2] 自動補0。迴圈條件 i<3 讓 i=1,2 都會執行,i=2 這一輪 score[2]=score[2]+10,也就是0+10=10。grade[2] 原本是字元 'C'("ABCDE" 的第3個字母),i=2 這一輪 grade[2]=grade[2]+1 把 'C' 加1變成 'D'。故 score[2]=10, grade[2]=D,選 (A)。
選項 B(score[2]=0, grade[2]=C)錯誤解析
這個答案完全沒有把迴圈的效果算進去,直接沿用了兩個陣列「修改前」的原始值——score[2] 自動補0的初始值(0)和 grade[2] 的原始字元('C'),忽略了迴圈條件 i<3 會讓 i=2 這一輪確實被執行到,兩個陣列在 i=2 這一輪都會被修改。
選項 C(score[2]=85, grade[2]=D)錯誤解析
grade[2] 算對了,但 score[2] 算錯了——這個答案可能把 score[1] 被加10後的結果(75+10=85)誤看成是 score[2] 的最終值,搞混了陣列中不同索引位置各自累加的結果。score[2] 應該是它自己原本的值(自動補0的0)加10,等於10,不是85。
選項 D(score[2]=10, grade[2]=C)錯誤解析
score[2] 算對了,但 grade[2] 算錯了——這個答案可能忽略了迴圈 i=2 這一輪也會修改 grade[2],誤以為 grade 陣列的修改只發生在 i=1 那一輪。事實上迴圈條件 i<3 讓 i=1 和 i=2 都會執行,grade[2] 也會被加1,從 'C' 變成 'D',不會維持原值 'C'。

10 考前衝刺 10 秒速記口訣 & 核心知識檢核清單

✅
陣列自動補0
有給部分初始值時,宣告個數多於給值個數的部分,一律自動補0,不是垃圾值。
✅
字串本質
字串就是以 '\0' 結尾的 char 陣列,%s 印到 '\0' 為止;strcmp 比內容,strlen 量長度,== 比位址。
✅
陣列與指標等價
p[i] 恆等於 *(p+i);若 p=&Data[2],則 *(p+3) 指向 Data[5],起點會跟著指標位移。
✅
變數遮蔽也能發生在陣列
區域陣列與全域指標同名時,區域陣列會遮蔽全域指標,函式內用的一律是區域版本。
✅
*ptr = *str 只改一個字元
解參考賦值一次只動一個字元,不是整串複製,複製整串要用 strcpy()。
✅
ASCII 連續遞增
'A'~'Z'、'a'~'z'、'0'~'9' 各自連續遞增,字元+1會得到順序上的下一個字元。
✅
二維字元陣列題型
先把每個索引對應的內容列成清單,再逐一模擬每個選項的索引順序,不要用猜的。