【考研C語言編程題】數組元素批量插入實現(含圖示+三部曲拆解)
一、題目要求
編寫C語言程序,實現將數組b
的所有元素批量插入到數組a
的指定位置(位置從0開始計數)。要求嚴格遵循“騰出空間→插入元素→更新長度”的操作三部曲,且需滿足以下條件:
- 數組
a
采用動態內存分配(支持長度動態擴展); - 需處理插入位置越界、內存分配失敗等異常情況;
- 禁止使用函數聲明,直接通過函數調用實現邏輯,主函數放在代碼最后;
- 插入后需打印原數組、待插入數組及插入結果,清晰展示過程。
二、插入過程圖示模擬
以“原數組a = [1, 3, 5, 7]
,待插入數組b = [2, 4]
,插入位置pos = 1
”為例,三步曲流程如下:
1. 初始狀態
- 原數組
a
(長度4):[1] [3] [5] [7]
- 待插入數組
b
(長度2):[2] [4]
- 插入位置
pos=1
:表示插入到a[1]
(元素3)之前
2. 第一步:騰出空間(擴容+元素后移)
- 擴容:原數組長度4 + 待插入長度2 = 新長度6,通過
realloc
擴展a
的內存空間; - 元素后移:從
a
的末尾元素(a[3]=7
)開始,將pos=1
及之后的元素(3、5、7)向后移動lenB=2
位,避免被覆蓋。
后移后a
的狀態:[1] [ ] [ ] [3] [5] [7]
(空位置用于存放b
的元素)
3. 第二步:插入元素
將b
的元素依次填入a
騰出的空位置(從pos=1
開始):
插入后a
的狀態:[1] [2] [4] [3] [5] [7]
4. 第三步:更新長度
將原數組a
的長度從4更新為6,完成插入。
三、完整代碼實現
#include <stdio.h>
#include <stdlib.h> // 包含動態內存操作函數(malloc、realloc、free)// 數組插入核心函數(直接定義,不單獨聲明)
int* insertArray(int* a, int* lenA, int* b, int lenB, int pos) {// 先做參數合法性校驗(避免異常操作)if (pos < 0 || pos > *lenA) { // 插入位置不能小于0或大于原數組長度printf("錯誤:插入位置不合法!\n");return NULL;}if (lenB == 0) { // 待插入數組無元素,無需操作printf("提示:待插入數組為空,無需插入!\n");return a;}// 第一步:騰出空間(擴容+元素后移)int newLen = *lenA + lenB; // 計算插入后的新長度// 擴容:用realloc擴展數組a的內存,返回新地址(原地址可能失效)int* newA = (int*)realloc(a, newLen * sizeof(int));if (newA == NULL) { // 內存分配失敗(如內存不足)printf("錯誤:內存分配失敗,無法擴容!\n");return NULL;}// 元素后移:從原數組末尾向前遍歷,避免覆蓋數據for (int i = *lenA - 1; i >= pos; i--) {newA[i + lenB] = newA[i]; // 每個元素后移lenB位}// 第二步:插入元素(將b的元素填入騰出的空間)for (int i = 0; i < lenB; i++) {newA[pos + i] = b[i]; // 從pos位置開始依次插入b的元素}// 第三步:更新長度(將新長度通過指針傳出)*lenA = newLen;return newA; // 返回插入后的新數組地址
}// 打印數組的輔助函數(用于展示數組內容)
void printArray(int* arr, int len, char* name) {printf("%s(長度%d):", name, len);for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");
}// 主函數(放在最后,邏輯更清晰)
int main() {// 1. 初始化原數組a(動態內存分配)int lenA = 4; // 原數組a的初始長度int* a = (int*)malloc(lenA * sizeof(int));if (a == NULL) { // 檢查內存分配是否成功printf("錯誤:原數組初始化失敗!\n");return 1;}// 給原數組a賦值:[1, 3, 5, 7]a[0] = 1;a[1] = 3;a[2] = 5;a[3] = 7;// 2. 初始化待插入數組b(靜態數組,無需動態分配)int b[] = {2, 4}; // 待插入的元素int lenB = sizeof(b) / sizeof(b[0]); // 計算b的長度(2)int insertPos = 1; // 插入位置(插入到a[1]之前)// 3. 打印插入前的數組printf("=== 插入前 ===\n");printArray(a, lenA, "原數組a");printArray(b, lenB, "待插入數組b");printf("插入位置:pos = %d\n\n", insertPos);// 4. 調用插入函數,執行插入操作a = insertArray(a, &lenA, b, lenB, insertPos);if (a == NULL) { // 檢查插入是否成功free(a); // 失敗時釋放已分配的內存,避免泄漏return 1;}// 5. 打印插入后的結果printf("=== 插入后 ===\n");printArray(a, lenA, "結果數組a");// 6. 釋放動態內存(避免內存泄漏,必須執行)free(a);a = NULL; // 避免野指針return 0;
}
四、代碼說明與考點分析
1. 核心邏輯拆解
- 騰出空間:通過
realloc
實現動態擴容,解決靜態數組長度固定的問題;元素從后向前移動,是避免數據覆蓋的關鍵(若從前往后移動,a[1]
會先被覆蓋,后續元素無法正確遷移)。 - 插入元素:通過循環將
b
的元素依次填入a
的空位置,索引關系為newA[pos+i] = b[i]
(i
從0到lenB-1
)。 - 更新長度:通過指針
lenA
將新長度傳出(因為函數參數是值傳遞,需用指針才能修改外部變量)。
2. 考研高頻考點
- 動態內存管理:
malloc
初始化數組、realloc
擴容、free
釋放內存,需理解“動態內存的生命周期由程序員控制”,避免內存泄漏和野指針。 - 數組操作邊界:插入位置的合法性校驗(
0 ≤ pos ≤ lenA
),是代碼健壯性的重要體現,考研編程題常考“異常情況處理”。 - 函數參數傳遞:通過指針傳遞數組長度,實現“函數修改外部變量”,需區分“值傳遞”和“地址傳遞”的差異。
五、運行結果
編譯運行代碼后,輸出如下(與圖示流程完全一致):
=== 插入前 ===
原數組a(長度4):1 3 5 7
待插入數組b(長度2):2 4
插入位置:pos = 1=== 插入后 ===
結果數組a(長度6):1 2 4 3 5 7
六、擴展思考(考研復試常問)
- 若需支持
float
或char
類型的數組插入,代碼需如何修改?(提示:將int
替換為對應類型,或使用宏定義實現泛型) - 多次插入時,頻繁調用
realloc
會影響效率,如何優化?(提示:預先分配更大的內存空間,減少擴容次數) - 若要實現“批量刪除數組元素”,思路與插入有何異同?(提示:刪除需先前移元素,再通過
realloc
縮小內存,最后更新長度)