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

C語言指針進階:二維數組、函數指針、數組指針與指針數組完全圖解

     編輯:關於C語言

一、三種「二維數組」指針形態

聲明含義佔用空間(32位)等價直觀形式
int** p;指向「一組 int* 指針」的指針4 bytesint p[x][y]; (x,y 動態)
int* p[5];5 個 int* 指針組成的數組20 bytesint p[5][x]; (行固定5,列動態)
int (*p)[5];指向「5 個 int 的數組」的指針4 bytesint p[x][5]; (列固定5,行動態)

使用差異

  • int** p:需兩次 malloc(先分配行指針數組,再逐行分配列)。
  • int* p[5]:編譯器已分配 5 指針槽,只需對每個 p[i] 分配列內存。
  • int (*p)[5]:一次性分配連續塊 malloc(sizeof(int)*5*k),p[i] 直接指向第 i 行首址。

二、函數指針 vs 指針函數

1. 函數指針——指向函數的指針

void MyFun(int x); 
void (*FunP)(int) = &MyFun; // 或直接 = MyFun 

// 調用等價寫法 
(*FunP)(10); 
FunP(10); // 編譯器自動解引用 

// 作為參數傳遞(回調模式) 
typedef void (*Callback)(int); 
void CallMyFun(Callback cb, int x) { cb(x); } 
CallMyFun(MyFun, 42);

本質:函數名 MyFun 是函數指針常量(地址不可改),FunP 是函數指針變量。類似 int vs int*。

2. 指針函數——返回指針的函數

char* copy_str(char* dst, const char* src) { 
    char* ret = dst; 
    while ((*dst++ = *src++)); 
    return ret; 
}

聲明格式:返回類型 *函數名(參數)。注意優先級:* 結合函數名,非參數。

三、數組指針 vs 指針數組

特性數組指針 int (*p)[n]指針數組 int* p[n]
本質單一指針,指向整個一維數組n 個指針組成的數組
步長p+1 跨越 n 個 intp+1 非法(數組名不可修改)
賦值二維數組p = a; (a 為 int a[m][n])需循環 p[i] = a[i];
訪問元素p[i][j] / *(*(p+i)+j)p[i][j] / *(*(p+i)+j)
內存佔用1 個指針大小n 個指針大小

四、統一訪問語法

無論哪種形式,最終均可用 p[i][j] 訪問元素,編譯器根據類型自動計算偏移:

  • *(*(p+i)+j):通用指針算術形式
  • (*(p+i))[j]:先解引用得行,再下標

五、避坑口訣

  1. [] 優先級高於 *:int* p[5] 是指針數組;int (*p)[5] 才是數組指針。
  2. 函數指針聲明:返回類型 (*名字)(參數),* 必須貼著名字。
  3. 二維數組傳參:void f(int a[][5]) 或 void f(int (*a)[5]),列數必須固定。
  4. 動態分配二維數組:優選 int (*p)[5] = malloc(sizeof(int)*5*rows) 連續內存,釋放只需 free(p)。

總結

指針類型系統嚴格對應內存佈局:** 多級間接、*[] 指針容器、(*)[] 整塊數組視圖。理解「類型即內存解釋規則」,配合 sizeof、typedef 輔助推導,即可駕馭所有複雜指針聲明。本文整理自 51CTO 技術博客「C中的幾組指針」。

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