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

C語言指標與陣列進階:函數傳遞陣列、二維陣列指標映射、字串指標操作

     編輯:關於C語言

陣列傳遞給函數:必須傳位址

C 採呼叫傳值,實參值複製給形參。若需在函數內修改陣列內容,必須傳遞陣列首元素位址(指標),在相同記憶體區間操作。

指標作函數參數的四種情況

無論實參/形參,指向陣列(一維/多維)的指標參數有四類組合:

情況實際參數形式參數說明
1陣列名指標變數最常用:func(arr) → void func(int *p)
2指標變數指標變數指標直接傳遞
3陣列名固定大小陣列參數void func(int p[10]) 實際退化為指標
4指標變數固定大小陣列參數同上
核心:函數參數宣告為 int p[] 或 int p[10] 等價於 int *p,編譯器視為指標,不檢查大小。

二維陣列指標映射原理

二維陣列記憶體按列主序連續儲存(Row-major)。

定義與指標關聯


int a[3][4];        // 3 列 4 行
int *ptr = a[0];    // ptr 指向首元素 a[0][0]

記憶體佈局:
a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] ... a[2][3]
ptr[0] ptr[1] ptr[2] ptr[3] ptr[4] ptr[5] ... ptr[11]

一維指標存取二維陣列元素

  • ptr[i] 對應 a[i/4][i%4](每列 4 元素)
  • 列索引 = i / 4,行索引 = i % 4

範例:尋找二維陣列最大值及其位置

主程式


#include 

main() {
    int a[3][4], *ptr, i, j, max, maxi, maxj;
    for (i = 0; i < 3; i++)
        for (j = 0; j < 4; j++)
            scanf("%d", &a[i][j]);

    ptr = a[0];                    // 傳首元素位址
    max_arr(ptr, &max, &maxi, 12); // 12 = 3*4 總元素數

    maxj = maxi % 4;  // 行索引
    maxi = maxi / 4;  // 列索引
    printf("max=%d, maxi=%d, maxj=%d", max, maxi, maxj);
}

函數實作


int max_arr(int *b, int *p1, int *p2, int n) {
    int i;
    *p1 = b[0];  // 最大值初始為首元素
    *p2 = 0;     // 位置初始為 0
    for (i = 1; i < n; i++)
        if (b[i] > *p1) {
            *p1 = b[i];
            *p2 = i;
        }
}

執行流程:將二維陣列視為一維連續空間,單一迴圈掃描 12 個元素找最大值與一維索引,主程式再轉換為二維列行索引。

指標與字元陣列(字串)

字元陣列名 = 首元素位址 = 字串起始位址


char str[20];
gets(str);
printf("%s\n", str);  // str 為 char*,符合 %s 期望

指標變數指向字串


char str[20], *p = str;  // p 指向 str 首位址
gets(str);
printf("%s\n", p);       // 以指標輸出字串

字元陣列 vs 字串關鍵差異

  • 字串:字元陣列的特殊形式,以 \0 結束
  • 儲存字串的陣列長度必須 ≥ 字串長度 + 1
  • 無 \0 的字元陣列不可用字串函數(printf("%s")、puts、strlen 等),只能逐字元處理

範例:無 \0 導致字串輸出錯誤


#include 

main() {
    char str[10], *p = str;
    int i;
    scanf("%s", str);           // 輸入超過 10 字元(無 \0 空間)
    for (i = 0; i < 10; i++)
        printf("%c", *p++);     // 正確:逐字元輸出
    printf("\n");
    p = str;
    printf("%s", p);            // 錯誤:無 \0,繼續讀取記憶體直到遇 0
    puts(str);                  // 錯誤:同理
}

指標實作字串複製與串接

複製:while(*ptr2) *ptr1++ = *ptr2++;


#include 

main() {
    char str1[30], str2[20], *ptr1 = str1, *ptr2 = str2;
    printf("input str1:"); gets(str1);
    printf("input str2:"); gets(str2);
    printf("str1------------str2\n%s.......%s\n", ptr1, ptr2);

    while (*ptr2) *ptr1++ = *ptr2++;  // 複製直到遇 \0
    *ptr1 = '\0';                     // 補上結束符

    printf("str1------------str2\n%s.......%s\n", str1, str2);
}

機制:*ptr2 為當前字元值,非 0 進入迴圈;*ptr1++ = *ptr2++ 依優先序先取值指派,再遞增指標。

串接:先移 ptr1 到尾端,再複製


while (*ptr1) ptr1++;          // 移動到 str1 結束符處
while (*ptr2) *ptr1++ = *ptr2++; // 附加 str2
*ptr1 = '\0';                  // 新結束符

前提:str1 空間 ≥ strlen(str1)+strlen(str2)+1。

指標運算優先序關鍵


*ptr1++  等價於  *(ptr1++)  // 先取值,指標遞增
(*ptr1)++  // 取值後,所指內容遞增(需括號)

重點總結

  1. 陣列傳函數修改內容 → 傳首元素位址(指標)
  2. 二維陣列連續儲存,一維指標可線性掃描,索引轉換:行 = i/列數, 列 = i%列數
  3. 字串 = 以 \0 結束的字元陣列,指標操作字串核心是 \0 判斷
  4. 無 \0 的字元陣列不可用字串函數,僅能逐字元處理
  5. 字串複製/串接指標版:while(*src) *dest++ = *src++; + 補 \0
  6. 空間檢查:目的緩衝區必須足夠大
  7. *ptr++ 先取值後遞增指標,非遞增所指內容
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved