C++測試題答案與講解
一、填空題答案及講解
- 答案:const
- 講解:在 C++ 中,const關鍵字用于定義常量,一旦定義,其值不能被修改。例如const int num = 10;,這里的num就是一個常量。
- 答案:3
- 講解:數組的下標從 0 開始,a[5] = {1, 2, 3, 4, 5};中,a[0]的值為 1,a[1]的值為 2,以此類推,a[2]的值就是 3。
- 答案:內存地址
- 講解:指針變量用于存儲其他變量的內存地址。通過指針,程序可以間接訪問和操作存儲在該地址的數據。例如int num = 5; int *p = #,這里的p就是一個指針,存儲了num變量的地址。
- 答案:常量表達式
- 講解:在switch語句中,每個case后面必須跟一個常量表達式。常量表達式在編譯時就能確定其值,這樣switch語句才能根據表達式的值準確地跳轉到對應的case分支。例如switch (day) { case 1: // 處理周一的情況; break; case 2: // 處理周二的情況; break; },這里的 1 和 2 就是常量表達式。
- 答案:先執行循環體,再判斷條件
- 講解:while循環是先判斷條件表達式,若條件為真則執行循環體;而do - while循環是先執行一次循環體,然后再判斷條件表達式,若條件為真則繼續執行循環體,否則退出循環。例如int i = 0; do { cout << i << " "; i++; } while (i < 3);,會先輸出 0,然后再判斷i < 3是否成立,繼續循環。
- 答案:enum
- 講解:enum關鍵字用于定義枚舉類型,它是一種用戶自定義的數據類型,用于將一組相關的常量組織在一起。例如enum Color { RED, GREEN, BLUE };,這里定義了一個Color枚舉類型,其中RED、GREEN、BLUE是枚舉常量,默認情況下,RED的值為 0,GREEN的值為 1,BLUE的值為 2。
- 答案:float、double
- 講解:float(單精度浮點數)和double(雙精度浮點數)用于表示帶有小數部分的數值。float通常占用 4 個字節,double通常占用 8 個字節,double的精度更高,能表示更精確的小數。例如float f = 3.14f; double d = 3.141592653589793;。
- 答案:delete[] p;
- 講解:當使用new運算符動態分配數組內存時,需要使用delete[]來釋放該內存,以避免內存泄漏。這里int *p = new int[10];分配了一個包含 10 個int類型元素的數組內存,delete[] p;則釋放了這塊內存。如果使用delete p;(少了[]),則只會釋放p指向的第一個元素的內存,而其他元素的內存將無法釋放,導致內存泄漏。
- 答案:邏輯與、邏輯或
- 講解:&&是邏輯與運算符,只有當左右兩邊的表達式都為真時,整個表達式才為真。例如(3 > 2) && (5 < 10),因為3 > 2為真,5 < 10也為真,所以整個表達式為真。||是邏輯或運算符,只要左右兩邊的表達式有一個為真,整個表達式就為真。例如(3 > 2) || (5 > 10),因為3 > 2為真,所以整個表達式為真。
- 答案:O(n^2)
- 講解:冒泡排序是一種簡單的排序算法。它通過多次比較相鄰元素并交換位置,將最大(或最小)的元素逐步 “冒泡” 到數組的末尾。在最壞情況下,即初始數組是逆序的,需要進行n(n - 1)/2次比較和交換操作,時間復雜度為O(n^2)。例如對于一個長度為n的數組,第一輪需要比較n - 1次,第二輪需要比較n - 2次,以此類推,總的比較次數為(n - 1) + (n - 2) +... + 1 = n(n - 1)/2,時間復雜度為O(n^2)。
二、選擇題答案及講解
- 答案:B
- 講解:char類型通常占用 1 個字節,用于存儲單個字符。int類型在不同系統下可能占用 2 個字節(如 16 位系統)或 4 個字節(如 32 位和 64 位系統);float類型通常占用 4 個字節;double類型通常占用 8 個字節。所以在這幾種數據類型中,char占用內存空間最小。
- 答案:D
- 講解:指針變量在使用前最好初始化,否則它會指向一個不確定的內存地址,可能導致程序崩潰,所以 A 選項錯誤。指針變量的值是它所指向變量的內存地址,而不是變量的值,B 選項錯誤。雖然可以對指針變量進行算術運算,如p++,但指針算術運算的結果是基于其所指向的數據類型的大小,并且指針算術運算必須在合理的范圍內,否則會導致未定義行為,C 選項不準確。指針變量通常只能指向同類型的變量,這樣才能保證對指針所指向內存的訪問和操作是安全和正確的,D 選項正確。
- 答案:B
- 講解:a > b? a : b是一個條件表達式,其含義是如果a > b為真,則返回a的值,否則返回b的值。因為a = 5,b = 3,5 > 3為真,所以該表達式的值為a的值,即 5。
- 答案:A
- 講解:在for(int i = 0; i < 10; i += 2)循環中,i的初始值為 0,每次循環后i增加 2。當i = 0時,滿足i < 10,執行循環體;i變為 2 后,仍滿足i < 10,繼續執行循環體;以此類推,當i依次變為 4、6、8 時都執行循環體,當i變為 10 時,不滿足i < 10,循環結束。所以循環體執行的次數為 5 次。
- 答案:D
- 講解:switch語句中default分支用于處理case常量表達式都不匹配的情況,它可以省略,A 選項正確。switch語句中case后面的值必須是常量表達式,這是語法要求,B 選項正確。switch語句中case分支可以有多個語句,如果沒有break語句,程序會繼續執行下一個case分支的語句,所以case分支的多個語句不需要用{}括起來,C 選項正確。switch語句中case分支后面的語句不一定必須以break結束,如果沒有break,會發生 “穿透” 現象,即繼續執行下一個case分支的語句,所以 D 選項錯誤。
- 答案:C
- 講解:在枚舉類型enum Week {Mon, Tue, Wed, Thu, Fri, Sat, Sun};中,枚舉常量默認從 0 開始編號,Mon的值為 0,Tue的值為 1,Wed的值為 2,以此類推。所以Wed的值為 2。
- 答案:B
- 講解:在 C++ 運算符優先級中,乘法運算符*的優先級高于加法運算符+,邏輯與運算符&&和等于運算符==。例如表達式3 + 4 * 2,先計算4 * 2,結果為 8,再計算3 + 8,結果為 11。所以在這幾個運算符中,*的優先級最高。
- 答案:B
- 講解:數組在定義后大小是固定的,不能改變,A 選項錯誤。數組名代表數組的首地址,這是數組的一個重要特性,通過數組名可以訪問數組中的元素,B 選項正確。通過數組名不能直接訪問數組元素,需要通過數組名加下標來訪問,例如arr[0],C 選項錯誤。數組元素的數據類型必須相同,這是數組的基本定義,D 選項錯誤。
- 答案:A
- 講解:在代碼int arr[5] = {1, 2, 3, 4, 5}; int *p = arr;中,p指向了數組arr的首地址。在for(int i = 0; i < 5; i++) { cout << *(p + i) << " "; }循環中,*(p + i)等價于arr[i],通過指針偏移依次訪問數組中的每個元素,并將其輸出。所以這段代碼實現的功能是輸出數組arr的元素。
- 答案:A
- 講解:穩定排序是指在排序過程中,相同元素的相對順序保持不變。冒泡排序在比較相鄰元素時,如果元素相等不會交換位置,所以它是穩定排序。快速排序、選擇排序和堆排序在某些情況下可能會改變相同元素的相對順序,屬于不穩定排序。例如,對于數組{2, 2, 1},冒泡排序后仍然是{1, 2, 2},相同元素的相對順序不變;而快速排序在某些劃分情況下,可能會將兩個2的相對順序改變。
三、判斷題答案及講解
- 答案:√
- 講解:在 C++ 中,變量必須先聲明后使用。聲明變量的作用是告訴編譯器變量的類型和名稱,以便編譯器為其分配內存空間。例如int num;聲明了一個int類型的變量num,之后才能對num進行賦值和其他操作。
- 答案:×
- 講解:字符串常量不能直接賦值給字符數組。例如char arr[10]; arr = "hello";這樣的寫法是錯誤的。應該使用strcpy函數來將字符串常量復制到字符數組中,如strcpy(arr, "hello");。這是因為字符數組名是一個常量指針,不能直接被賦值。
- 答案:×
- 講解:指針變量通常指向同類型的變量。雖然可以通過強制類型轉換讓指針指向不同類型的變量,但這樣做可能會導致未定義行為,因為不同類型的變量在內存中的存儲方式和大小可能不同。例如int num = 5; char *p = (char *)#,這樣的操作可能會導致訪問內存錯誤,因為char類型和int類型的大小不同。
- 答案:√
- 講解:if - else語句可以嵌套使用,以實現更復雜的條件判斷邏輯。例如if (a > 10) { if (b > 20) { // 內層if語句 } else { // 內層else語句 } } else { // 外層else語句 },通過嵌套可以根據不同的條件執行不同的代碼塊。
- 答案:×
- 講解:while循環是先判斷條件表達式,若條件為真則執行循環體,若條件一開始就為假,則循環體一次都不會執行。例如int i = 5; while (i > 10) { // 循環體 },由于i > 10為假,循環體不會執行。
- 答案:√
- 講解:枚舉類型的元素默認從 0 開始編號。例如enum Season { SPRING, SUMMER, AUTUMN, WINTER };,SPRING的值為 0,SUMMER的值為 1,AUTUMN的值為 2,WINTER的值為 3。當然,也可以在定義枚舉類型時指定元素的值,如enum Season { SPRING = 1, SUMMER, AUTUMN, WINTER };,此時SUMMER的值為 2,AUTUMN的值為 3,WINTER的值為 4。
- 答案:√
- 講解:數組名作為函數參數傳遞時,傳遞的是數組的首地址。這意味著在函數內部對數組元素的修改會影響到原數組。例如void modifyArray(int arr[], int n) { arr[0] = 100; },調用該函數時,傳遞的數組首地址使得函數內部對arr[0]的修改會改變原數組第一個元素的值。
- 答案:√
- 講解:邏輯運算符&&和||具有短路特性。對于&&運算符,如果左邊的表達式為假,則右邊的表達式不會被計算,因為整個表達式已經確定為假。例如(false && someFunction()),someFunction()不會被調用。對于||運算符,如果左邊的表達式為真,則右邊的表達式不會被計算,因為整個表達式已經確定為真。例如(true || someFunction()),someFunction()不會被調用。
- 答案:×
- 講解:動態分配的內存(使用new運算符分配的內存)需要手動釋放(使用delete或delete[]運算符),否則程序結束時系統不會自動回收,會造成內存泄漏。例如int *p = new int;,在使用完p后,需要使用delete p;來釋放內存;如果是動態分配的數組int *arr = new int[10];,則需要使用delete[] arr;來釋放內存。
- 答案:×
- 講解:排序算法的時間復雜度不僅與數據規模有關,還與初始數據的順序有關。例如冒泡排序,在初始數組已經有序的情況下,時間復雜度為O(n),因為只需要進行一輪比較,沒有元素交換;而在初始數組逆序的情況下,時間復雜度為O(n^2)。插入排序也類似,在初始數組有序時,時間復雜度為O(n)。所以排序算法的時間復雜度與初始數據順序有關。
四、編程題答案及講解
1. 冒泡排序函數
void bubbleSort(int arr[], int n) { ????for (int i = 0; i < n - 1; i++) { ????????for (int j = 0; j < n - i - 1; j++) { ????????????if (arr[j] > arr[j + 1]) { ????????????????int temp = arr[j]; ????????????????arr[j] = arr[j + 1]; ????????????????arr[j + 1] = temp; ????????????} ????????} ????} } |
- 講解:
- 外層循環for (int i = 0; i < n - 1; i++)控制排序的輪數。對于一個長度為n的數組,最多需要進行n - 1輪排序就能將數組排好序。
- 內層循環for (int j = 0; j < n - i - 1; j++)用于比較相鄰元素并交換位置。在每一輪排序中,比較的次數會隨著輪數的增加而減少,因為每一輪都會將一個最大(或最小)的元素 “冒泡” 到數組的末尾。
- if (arr[j] > arr[j + 1])判斷相鄰的兩個元素arr[j]和arr[j + 1]的大小關系,如果arr[j]大于arr[j + 1],則交換它們的位置。通過int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp;這三行代碼實現交換。經過多輪比較和交換,最終數組會按從小到大的順序排列。
2. 尋找數組最大值和最小值的程序
#include <iostream> using namespace std; int main() { ????int n; ????cout << "請輸入整數的個數: "; ????cin >> n; ????int arr[n]; ????cout << "請輸入" << n << "個整數: "; ????for (int i = 0; i < n; i++) { ????????cin >> arr[i]; ????} ????int maxVal = arr[0]; ????int minVal = arr[0]; ????for (int i = 1; i < n; i++) { ????????if (arr[i] > maxVal) { ????????????maxVal = arr[i]; ????????} ????????if (arr[i] < minVal) { ????????????minVal = arr[i]; ????????} ????} ????cout << "數組中的最大值為: " << maxVal << endl; ????cout << "數組中的最小值 |