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

C語言指針進階(四):二維數組指針、字符串指針、函數指針與指針函數

     編輯:C 語言基礎

二維數組指針變量


int a[3][4];
int (*p)[4] = a;  // p 指向首行,類型 int (*)[4]
// p+i -> 第 i 行
// *(p+i) -> 第 i 行數組,退化為 int* 指向行首
// *(*(p+i)+j) -> a[i][j]
  • 聲明括號不可省:int (*p)[4] vs int *p[4](指針數組)。
  • 列數(4)必須為常量(或 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));

字符串指針變量


char *ps = "C Language";  // 指向字面量(只讀區)
// 等價分兩步
char *ps; ps = "C Language";

// 指針算術跳過前綴
ps += 10;  // 指向 "guage"
printf("%s\n", ps);  // guage

字符串指針 vs 字符數組

特性字符串指針 char *ps字符數組 char str[]
存儲指針變量存地址,字符串在只讀區/堆數組元素直接存字符,棧/靜態區
初始化char *ps = "abc"; 合法需靜態/外部:static char str[] = "abc";
賦值ps = "new"; 合法(改指向)str = "new"; 非法,需逐字符拷貝
修改指向字面量時不可改;指向堆/棧可改隨時可改
sizeof指針大小 (4/8)數組總字節數

字符串指針作函數參數


// 只讀輸入用 const
void print_str(const char *s) {
    while (*s) putchar(*s++);
}

// 需修改目標緩衝區
void my_strcpy(char *dst, const char *src) {
    while (*dst++ = *src++);
}

函數指針變量

函數名 = 函數入口地址。可賦值給函數指針變量,通過它調用函數。

聲明語法


返回類型 (*指針變量名)(參數列表);

示例:通過指針調用 max


int max(int a, int b) { return a>b?a:b; }

int main() {
    int (*pmax)(int, int) = max;  // 賦值函數地址
    int x=3, y=5, z;
    z = (*pmax)(x, y);            // 調用:(*指針)(實參)
    // 或 z = pmax(x, y);  // C 允許隱式解引用
    printf("max=%d\n", z);
    return 0;
}

關鍵規則

  • 括號不可省:int (*p)(int,int) 是函數指針;int *p(int,int) 是返回指針的函數聲明。
  • 不可算術運算:函數指針無 ++/--/+n,無意義。
  • 調用語法:(*pmax)(x,y) 或 pmax(x,y)。

指針函數(返回指針的函數)


返回類型 *函數名(參數列表);

示例:返回星期名字符串


const char *day_name(int n) {
    static const char *names[] = {
        "Illegal", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday", "Sunday"
    };
    return (n<1 || n>7) ? names[0] : names[n];
}

int main() {
    int d;
    scanf("%d", &d);
    if (d < 0) return 1;
    printf("Day %d -> %s\n", d, day_name(d));
    return 0;
}
  • 返回靜態字符串指針,生命周期覆蓋整個程序,安全。
  • 返回局部數組指針是嚴重錯誤(懸空指針)。

函數指針 vs 指針函數 對比

項目函數指針變量指針函數
聲明int (*p)(int,int);int *p(int,int);
本質變量,存函數地址函數,返回指針值
括號位置(*p) 綁定標識符*p 綁定返回類型
用途回調、策略模式、狀態機工廠函數、查找返回指針

指針數組

數組元素為指針。常用於存儲字符串指針集合。

聲明


int *pa[3];           // 3 個 int*
char *names[8] = {    // 字符串指針數組
    "Illegal", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday", "Sunday"
};

作函數參數:字符串排序(交換指針而非字符串)


#include 

void sort(char *name[], int n) {
    for (int i=0; i 0) k = j;
        if (k != i) {
            char *tmp = name[i];
            name[i] = name[k];
            name[k] = tmp;  // 僅交換指針,極快
        }
    }
}

void print(char *name[], int n) {
    for (int i=0; i

總結

  • 二維數組指針 int (*p)[N] 攜帶列數,高效計算行偏移。
  • 字符串指針靈活但需注意只讀區與可寫緩衝區區別,const 表達只讀意圖。
  • 函數指針變量實現間接調用,核心語法 返回類型 (*名)(參數),括號定乾坤。
  • 指針函數返回指針,慎防返回局部地址。
  • 指針數組交換指針而非數據,大幅提升排序等操作效率。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved