主页 > IT业界  > 

二级指针略解【C语言】

二级指针略解【C语言】
以int** a为例       1.二级指针的声明

a 是一个指向 int*(指向整型的指针)的指针,即二级指针。

通俗的讲,a是一个指向指针的指针,对a解引用会是一个指针。

它可以用于操作动态分配的二维数组、指针数组或需要间接修改指针的场景。

2.动态二维数组的表示

例如动态分配一个 N×M 的二维数组:

int** a =(int**)malloc(N*sizeof(int*)); for(int i=0;i<N;i++){ *(a+i)=(int*)malloc(M*sizeof(int)); //a[i]=(int*)malloc(M*sizeof(int)); } 3.函数参数传递

当二级指针作为函数参数传递是,有以下几种意思:

1.作为指针数组使用: void example(int** a,int size){ for(int i=0;i<size;i++){ a[i]=NULL;//初始化 } } 2.作为二维数组使用: void example(int** a,int size,int* aColSize){ for(int i=0;i<size;i++){ for(int j=0;j<aColSize[i];j++){ a[i][j]=0;//初始化 } } } 3.作为传回的指针使用: void example(int** a){ *a=NULL; }

和这段代码是一样的作用:

int* example(int* a){ a=NULL; return a; } 注意: 1.混淆二维数组和二级指针

虽然二级指针作为函数参数传递可以作为二维数组使用,但不能将二维数组作为二级指针接收的参数使用!

例如以下是错误做法:

#include<stdio.h> void example(int** a,int size,int* aColSize){ for(int i=0;i<size;i++){ for(int j=0;j<aColSize[i];j++){ a[i][j]=0;//初始化 } } } int main() { int a[10][10],size=10,aColSize[10]; for(int i=0;i<10;i++){ aColSize[i]=10; for(int j=0;j<10;j++){ scanf("%d",&a[i][j]); } } example(a,size,aColSize);//错误:企图将二维数组作为二级指针接收的参数 return 0; }

正确做法应该这样做:

#include<stdio.h> #include<stdlib.h> void example(int** a, int size, int* aColSize) { for (int i = 0; i < size; i++) { for (int j = 0; j < aColSize[i]; j++) { a[i][j] = 0; //初始化 printf("%d_%d ", i, j); } } } int main() { int *a[10], size = 10, aColSize[10]; for (int i = 0; i < size; i++) { a[i] = (int*)malloc(10*sizeof(int)); } for (int i = 0; i < size; i++) { aColSize[i] = size; for (int j = 0; j < size; j++) { scanf("%d", &a[i][j]); } } example(a, size, aColSize); for(int i=0;i<size;i++){ free(a[i]); } return 0; }

千万不要写成以下这样,虽然编译器可能不会报错,但向野指针指向的区域赋值是不可取的,程序会崩溃的。

#include<stdio.h> #include<stdlib.h> void example(int** a, int size, int* aColSize) { for (int i = 0; i < size; i++) { for (int j = 0; j < aColSize[i]; j++) { a[i][j] = 0; //初始化 printf("%d_%d ", i, j); } } } int main() { int *a[10], size = 10, aColSize[10];//a数组未初始化 for (int i = 0; i < size; i++) { aColSize[i] = size; for (int j = 0; j < size; j++) { scanf("%d", &a[i][j]); } } example(a, size, aColSize); return 0; }

二级指针用来作为动态二维数组时,分配的内存是不连续的,但静态分配的二维数组在内存上是连续的!因此,也不能将静态二维数组的首元素地址赋给二级指针!

以下是错误示例:

int arr[3][4]; int **p = (int**)arr; // ❌ 编译通过但运行崩溃 2.动态内存释放

虽然程序一般在运行结束后会自动释放所用内存,但为保证程序长时间运行内存足够,因此用malloc等函数动态分配的内存在使用后要释放!一般称其为避免内存泄漏。养成用完释放的好习惯,避免工作时的项目出错。

但内存释放对于二级指针一定要有先后顺序:

以下是错误示范1:

void example(){ int N,M; scanf("%d %d",&N,&M); int** a=(int**)malloc(N*sizeof(int*)); for(int i=0;i<N;i++){ a[i]=(int*)malloc(M*sizeof(int)); } free(a);//只释放了a数组,但未释放a+i(0<i<10)这些数组! }

以下是错误示范2:

void example(){ int N,M; scanf("%d %d",&N,&M); int** a=(int**)malloc(N*sizeof(int*)); for(int i=0;i<N;i++){ a[i]=(int*)malloc(M*sizeof(int)); } free(a); for(int i=0;i<N;i++){ free(a[i]);//由于a数组的内存已经释放,a[i]的指针信息丢失,无法释放内存! } }

以下是正确示例:

void example(){ int N,M; scanf("%d %d",&N,&M); int** a=(int**)malloc(N*sizeof(int*)); for(int i=0;i<N;i++){ a[i]=(int*)malloc(M*sizeof(int)); } for(int i=0;i<N;i++){ free(a[i]); } free(a); }

关键要点总结

✅ 二级指针本质:指向指针的指针

✅ 正确使用场景:动态多维数组、需间接修改指针

⚠️ 常见错误:混淆静态/动态内存布局、未初始化指针

🔧 最佳实践:分配后立即初始化、使用完毕及时释放  

标签:

二级指针略解【C语言】由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“二级指针略解【C语言】