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

C 語言數組完全指南:一維數組聲明、初始化、遍歷、冒泡排序與最大最小值查找實戰

     編輯:關於C語言

C 語言數組完全指南:一維數組核心操作實戰

數組是 C 語言中批量管理同類型數據的基礎結構。本文系統講解一維數組的聲明、初始化、內存佈局、遍歷訪問、經典算法(最大最小值、冒泡排序)與邊界安全實踐。

一、數組聲明與初始化

// 1. 聲明並靜態初始化
int scores[5] = {90, 85, 78, 92, 88};      // 長度由初始化列表推導
int scores[5] = {90, 85};                  // 剩餘元素自動置 0
char name[] = "Hello";                     // 長度 6(含 \0)

// 2. 聲明後賦值
int arr[10];
for (int i = 0; i < 10; i++) arr[i] = i * 2;

// 3. 部分初始化 = 全零初始化
int zeros[100] = {0};  // 全部為 0

// 4. 變長數組(C99,棧上分配,慎用大尺寸)
int n; scanf("%d", &n);
int vla[n];  // 運行時確定大小,函數返回自動釋放

二、內存佈局與訪問

  • **連續內存**:int a[5] 佔用 5 * sizeof(int) 字節,元素地址遞增 sizeof(int)。
  • **下標訪問** a[i] 等價 **指針算術** *(a + i),編譯器自動按類型大小縮放。
  • **數組名** 在表達式中退化為指向首元素的指針(int *),但 sizeof(a) 返回整個數組大小,**不退化**。
  • **越界訪問** 未定義行為(UB),輕則數據錯誤,重則崩潰/安全漏洞,**必須手動保證索引合法**。

三、經典實戰案例

案例 1:輸入 5 個整數,求最大值與最小值

int a[5];
printf("輸入 5 個整數: ");
for (int i = 0; i < 5; i++) scanf("%d", &a[i]);

int max = a[0], min = a[0];
for (int i = 1; i < 5; i++) {
    if (a[i] > max) max = a[i];
    if (a[i] < min) min = a[i];
}
printf("最大值: %d, 最小值: %d\n", max, min);

案例 2:冒泡排序(升序)

int arr[5] = {1, 5, 9, 3, 4};
int n = 5;

// 外層控制輪數:n-1 輪
for (int i = 0; i < n - 1; i++) {
    // 內層兩兩比較交換,每輪將最大值「冒泡」到末尾
    for (int j = 0; j < n - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
            int tmp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = tmp;
        }
    }
}

printf("排序後: ");
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n");  // 輸出: 1 3 4 5 9

四、進階話題

1. 數組作為函數參數

// 三種等價聲明
void printArr(int arr[], int n);
void printArr(int *arr, int n);
void printArr(int arr[10], int n);  // 10 被忽略,僅作文檔

// 調用時退化為指針,**內部無法獲取長度**,必須額外傳遞 n
// 內部 sizeof(arr) 返回指針大小(4/8),而非數組大小

2. 多維數組(二維)

int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};
// 內存按行主序連續佈局
// 訪問:matrix[row][col]
// 作為參數:void func(int matrix[][4], int rows) —— 必須指定列數

3. 動態數組(堆分配)

int n; scanf("%d", &n);
int *dyn = (int*)malloc(n * sizeof(int));
if (!dyn) { perror("malloc"); return 1; }

for (int i = 0; i < n; i++) dyn[i] = i * i;
// 使用完畢
free(dyn);
dyn = NULL;

4. 字符數組與字符串

  • char str[] = "Hello"; → 長度 6,末尾自動 \0。
  • char buf[100]; fgets(buf, sizeof(buf), stdin); 安全讀取一行(含換行符)。
  • 字符串函數(strlen/strcpy/strcmp)依賴 \0 結束符,**必須保證緩衝區足夠大且以 \0 結尾**。

五、避坑清單

  1. 越界訪問:循環條件 i <= n 應為 i < n。
  2. 未初始化:局部數組不自動清零,讀取前必須初始化。
  3. 函數參數 sizeof 失效:數組退化為指針,sizeof(ptr) 非數組大小。
  4. 棧溢出:大數組(>1MB)改用動態分配(malloc/calloc)。
  5. 字符串缺 \0:strncpy 不保證以 \0 結尾,手動補齊。
  6. 釋放後使用:free(ptr) 後置 NULL,防止雙重釋放/野指針。

六、最佳實踐

  • 優先使用標準庫算法:qsort(快速排序)、bsearch(二分查找)、memcpy/memmove(高效複製)。
  • 定義常量 #define ARR_LEN(arr) (sizeof(arr)/sizeof(arr[0])) 僅適用於**作用域內的數組**,不適用於指針參數。
  • 結構體數組實現異構數據聚合:struct Student { char name[20]; int age; } class[50];。
  • 嵌入式/高性能場景考慮內存對齊、緩存行友好佈局(AoS vs SoA)。

熟練掌握數組聲明、初始化、遍歷、排序查找、動態分配與函數傳遞細節,是 C 語言數據處理能力的基石,也是指針算術、內存管理理解的最佳切入點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved