C语言学习第24篇---多维数组和多维指针

举报
CodeAllen 发表于 2021/10/29 23:00:00 2021/10/29
【摘要】 知识来源主要是陈正冲老师的《C语言深度解剖》及Delphi Tang老师的《C语言剖析》和《征服C指针》,《C和指针》,有兴趣的朋友可以看我置顶文章获取   指向指针的指针 指针的本质是变量指针会占用一定的内存空间可以定义指针的指针来保存指针变量的地址值 int main(){ int i = 0; int* p = N...

知识来源主要是陈正冲老师的《C语言深度解剖》及Delphi Tang老师的《C语言剖析》和《征服C指针》,《C和指针》,有兴趣的朋友可以看我置顶文章获取

 

指向指针的指针

  • 指针的本质是变量
  • 指针会占用一定的内存空间
  • 可以定义指针的指针来保存指针变量的地址值

  
  1. int main()
  2. {
  3. int i = 0;
  4. int* p = NULL;
  5. int** pp = NULL;
  6. pp = &p;
  7. *pp = &i;
  8. return 0;
  9. }

 

可能会有疑问:问什么需要指向指针的指针?

  • 指针在本质上也是变量
  • 对于指针也同样存在传值调用与传址调用

 

实例1:重置动态空间大小


  
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. int reset(char**p, int size, int new_size) //定义的二维指针
  4. {
  5. int ret = 1;
  6. int i = 0;
  7. int len = 0;
  8. char* pt = NULL;
  9. char* tmp = NULL;
  10. char* pp = *p;
  11. if( (p != NULL) && (new_size > 0) ) //安全性检测
  12. {
  13. pt = (char*)malloc(new_size); //动态申请一段内存空间
  14. tmp = pt;
  15. len = (size < new_size) ? size : new_size; //判断新分配的空间与之前的比较大小
  16. for(i=0; i<len; i++)
  17. {
  18. *tmp++ = *pp++;
  19. }
  20. free(*p);
  21. *p = pt; //改变内存地址
  22. }
  23. else
  24. {
  25. ret = 0;
  26. }
  27. return ret;
  28. }
  29. int main()
  30. {
  31. char* p = (char*)malloc(5);
  32. printf("%p\n", p); //这是打印重新分配前地址值
  33. if( reset(&p, 5, 3) ) //假设申请的空间用不完,可以再次改变,使用reset函数,将p对应的内存空间又5变为3
  34. {
  35. printf("%p\n", p); //实际发现变化了----就是指针的传址调用
  36. }
  37. free(p); //释放内存
  38. return 0;
  39. }

 

二维数组和二维指针

  • 二维数组在内存中是以一维的方式排布的
  • 二维数组的第一维是一维数组
  • 二维数组的第二维是具体的值
  • 二维数组可以看做常量指针

如图所示:

 

实例2:遍历二维数组


  
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. void printArray(int a[], int size)
  4. {
  5. int i = 0;
  6. printf("printArray: %d\n", sizeof(a));
  7. for(i=0; i<size; i++)
  8. {
  9. printf("%d\n", a[i]);
  10. }
  11. }
  12. int main()
  13. {
  14. int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; //二维数组的初始化,这已经是矩阵的思想了
  15. int* p = &a[0][0];
  16. int i = 0;
  17. int j = 0;
  18. for(i=0; i<3; i++)
  19. {
  20. for(j=0; j<3; j++)
  21. {
  22. printf("%d, ", *(*(a+i) + j)); //*(a+i) ==> a[i] ,*(a[i]+j) ==> a[i][j] 数组可读性好
  23. }
  24. printf("\n");
  25. }
  26. printf("\n");
  27. printArray(p, 9);
  28. return 0;
  29. }

 

数组:

  • 一维数组名代表数组首元素的地址

   int a[5]    a的类型为int*

  • 二维数组名同样代表数组首元素的地址

   int m[2][5]    m的类型为int(*)[5]

 

结论:

  1. 二维数组名可以看做指向数组的常量指针
  2. 二维数组可以看做是一维数组
  3. 二维数组中的每一个元素都是同类型的一维数组

 

实例3:申请动态二维数组


  
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. int** malloc2d(int row, int col) //二维指针
  4. {
  5. int** ret = NULL;
  6. if( (row > 0) && (col > 0) )
  7. {
  8. int* p = NULL;
  9. ret = (int**)malloc(row * sizeof(int*)); //先申请一个一维数组
  10. p = (int*)malloc(row * col * sizeof(int)); //这个之前是 p = (int*)malloc(row * col); 会造成内存越界的情况
  11. if( (ret != NULL) && (p != NULL) ) //安全检查
  12. {
  13. int i = 0;
  14. for(i=0; i<row; i++)
  15. {
  16. ret[i] = p + i * col;
  17. }
  18. }
  19. else
  20. {
  21. free(ret);
  22. free(p);
  23. ret = NULL;
  24. }
  25. }
  26. return ret;
  27. }
  28. void free2d(int** p)
  29. {
  30. if( *p != NULL )
  31. {
  32. free(*p); //释放
  33. }
  34. free(p);
  35. }
  36. int main()
  37. {
  38. int** a = malloc2d(3, 3); //得到一个2*3的二维数组
  39. int i = 0;
  40. int j = 0;
  41. for(i=0; i<3; i++)
  42. {
  43. for(j=0; j<3; j++)
  44. {
  45. printf("%d, ", a[i][j]);
  46. }
  47. printf("\n");
  48. }
  49. free2d(a);
  50. return 0;
  51. }

 

小结:

  • 1.C语言其实只支持一维数组
  • 2.C语言中的数组大小必须在编译器就作为常数确定
  • 3.C语言的数组元素可是任何类型的数据
  • 4.C语言的数组的元素可以是另一个数组

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/89110916

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。