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

C語言指針進階(三):數組指針、多維數組指針與地址運算

     編輯:C 語言基礎

數組指針基礎

數組名是首元素地址常量,數組指針變量可指向數組或數組元素,支援算術運算。

一維數組指針


int a[5] = {1,2,3,4,5};
int *pa = a;        // pa 指向 a[0]
// 等價關係:
// pa == a == &a[0]
// pa+1 == a+1 == &a[1]
// *(pa+i) == a[i]

兩種訪問方式

  1. 下標法:a[i],直觀、編譯器自動計算偏移。
  2. 指針法:*(pa+i) 或 pa[i],本質相同,指針算術顯式化。

指針遍歷數組


// 方式 1:指針遞增
int *pa = a;
for (int i = 0; i < 5; ++i) {
    printf("%d ", *pa++);
}

// 方式 2:指針與下標混用
for (int i = 0; i < 5; ++i) {
    printf("%d ", pa[i]);
}

// 方式 3:範圍 for (C99 VLA 或 C++)
int *end = a + 5;
for (int *p = a; p < end; ++p) {
    printf("%d ", *p);
}

數組名/指針作函數參數

數組作參數退化為指針,實際傳遞首元素地址。形參可寫 int *pa 或 int pa[] 或 int pa[5](長度被忽略)。

示例:計算平均分


float average(float *scores, int n) {
    float sum = 0;
    for (int i = 0; i < n; ++i) sum += scores[i];  // 或 *scores++
    return sum / n;
}

int main() {
    float s[5] = {80, 90, 85, 95, 70};
    printf("Avg: %.2f\n", average(s, 5));  // s 退化為 float*
}

多維數組指針核心

二維數組 int a[3][4] 在內存中按行主序連續存儲。關鍵類型:

  • a 類型:int (*)[4](指向含 4 個 int 的數組的指針)。
  • a[0] / *a 類型:int[4],退化為 int* 指向 a[0][0]。
  • &a[0][0] 類型:int*。
  • a+1 指向第 2 行,偏移 4*sizeof(int) 字節。

地址等價表

表達式類型值(假設 a 基址 1000,int 4 字節)
aint (*)[4]1000
a[0]int* (退化)1000
*aint* (退化)1000
&a[0][0]int*1000
a+1int (*)[4]1016
a[1]int*1016
*(a+1)int*1016
&a[1][0]int*1016

元素訪問公式


// a[i][j] 等價形式:
*(a[i] + j)          // a[i] 退化為行首指針
*(*(a + i) + j)      // a+i 指向第 i 行,解引用得行首指針
// 統一公式:*(*(a + i) + j)

指向二維數組的指針變量


int a[3][4] = {...};
int (*p)[4] = a;   // p 指向整個二維數組(實為指向首行)
// p+1 指向第 2 行
// *(p+i)+j 是 a[i][j] 地址
// *(*(p+i)+j) 是 a[i][j] 值
  • 聲明必須帶括號:int (*p)[4]。int *p[4] 是指針數組(4 個 int*),完全不同。
  • 第二維長度(列數)必須常量(C99 VLA 除外),編譯器據此計算行偏移。

完整遍歷示例


int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int (*p)[4] = a;
for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 4; ++j) {
        printf("%2d ", *(*(p+i)+j));
    }
    printf("\n");
}

字符串指針


char *ps = "C Language";  // ps 指向只讀字符串字面量區
// 等價
char *ps; ps = "C Language";

// 指針算術:跳過前 10 字符
ps += 10;  // 指向 'g'
printf("%s\n", ps);  // 輸出 "guage"
  • 字符串字面量存儲在只讀區,不可修改(ps[0] = 'x' → UB)。
  • 若需可修改緩衝區:char buf[] = "C Language"; 或 malloc。

字符串指針作函數參數:strcpy 實現


void my_strcpy(char *dst, const char *src) {
    while ((*dst++ = *src++) != '\0');
    // 或精簡:while (*dst++ = *src++);
}

int main() {
    char *src = "CHINA";
    char dst[10];
    my_strcpy(dst, src);
    printf("%s\n", dst);  // CHINA
}
  • const char *src 保護源字符串不被修改。
  • *dst++ = *src++ 結合賦值、遞增、判斷,極度精簡。

總結

  • 數組指針 = 首元素地址 + 算術能力,兩種訪問方式等價。
  • 二維數組指針 int (*p)[N] 攜帶列數信息,編譯器自動計算行偏移。
  • int *p[N] 是指針數組,int (*p)[N] 是數組指針,括號決定一切。
  • 字符串指針指向字面量(只讀)或堆/棧緩衝區(可寫),const 正確表達意圖。
  • 指針遍歷 for(p=begin; p 是 C 風格標準範式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved