24 多维数组和多维指针

1 指向指针的指针

  • 指针的本质是变量

  • 指针会占用一定的内存空间

  • 可以定义指针的指针来保存指针变量的地址值

  • 示例

    int main()
    {
        int i = 0;
        int* p = NULL;
        int** pp = NULL;
        
        pp = &p;
        *pp = &i; //=> p = &i;
        
        return 0;
    }
    
  • 为什么需要指向指针的指针?

    • 指针在本质上也是变量
    • 对于指针也同样存在传值调用传址调用
  • 示例:重置动态空间大小

    • Demo

      #include <stdio.h>
      #include <malloc.h>
      
      int reset(char**p, int size, int new_size){
          int ret = 1;
          int i = 0;
          int len = 0;
          char* pt = NULL;
          char* tmp = NULL;
          char* pp = *p;  //pp指向原先的内存空间
         
          if( (p != NULL) && (new_size > 0) ){  //安全性检测
              //重新申请一块大小为new_size的新的内存空间
              pt = (char*)malloc(new_size);
              
              //将原先内存空间中的数据复制到新的内存空间中
              tmp = pt;
              
              //取小的进行复制
              len = (size < new_size) ? size : new_size;
              
              //复制:pp->tmp
              for(i=0; i<len; i++){
                  *tmp++ = *pp++;      
              }
              
              //释放原先的内存空间
              free(*p);
              //将指针指向新的内存空间
              *p = pt;
          }
          else{
              ret = 0;
          }
          
          return ret;
      }
      
      int main()
      {
          char* p = (char*)malloc(5);
          
          printf("%p\n", p);
          
          if( reset(&p, 5, 3) ){
              printf("%p\n", p);
          }
      
          free(p);
          
          return 0;
      }
      
    • 运行

      0x9678008
      0x9678018
      

2 二维数组与二级指针

  • 二维数组在内存中以一维的方式排布

  • 二维数组中的第一维是一维数组

  • 二维数组中的第二维才是具体的值

  • 二维数组的数组名可看作常量指针

  • 示例:遍历二维数组

    • Demo

      #include <stdio.h>
      #include <malloc.h>
      
      void printArray(int a[], int size)
      {
          int i = 0;
          
          printf("printArray: %d\n", sizeof(a));
      
          for(i=0; i<size; i++){
              printf("%d\n", a[i]);
          }
      }
      
      int main()
      {
          int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};
          int* p = &a[0][0];
          
          int i = 0;
          int j = 0;
          
          for(i=0; i<3; i++){
              for(j=0; j<3; j++){
                  printf("%d, ", *(*(a+i) + j));  //*(a+i)得到的是一个一维数组的数组名。*(a+i)=>a[i],*(a[i]+j)=>a[i][j]
              }
              
              printf("\n");
          }
          
          printf("\n");
          
          printArray(p, 9);
          
          return 0;
      }
      
    • 运行

      0,1,2,
      3,4,5,
      6,7,8,
      
      printArray: 4
      0
      1
      2
      3
      4
      5
      6
      7
      8
      
  • 数组名

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

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

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

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

  • 结论

    • 二维数组名可以看作是指向数组的常量指针
    • 二维数组可以看作是一维数组
    • 二维数组中的每个元素都是同类型的一维数组
  • 示例:如何动态申请二维数组

    • Demo

      #include <stdio.h>
      #include <malloc.h>
      
      int** malloc2d(int row, int col)
      {
          int** ret = NULL;
          
          if( (row > 0) && (col > 0) ){
              int* p = NULL;
              
              ret = (int**)malloc(row * sizeof(int*));
              p = (int*)malloc(row * col * sizeof(int));
              
              if( (ret != NULL) && (p != NULL) ){
                  int i = 0;
                  
                  for(i=0; i<row; i++){
                      ret[i] = p + i * col;
                  }
              }
              else{
                  free(ret);
                  free(p);
                  
                  ret = NULL;
              }
              
          }
          
          return ret;
      }
      
      void free2d(int** p){
          if( *p != NULL ){
              free(*p);
          }
          
          free(p);
      }
      
      int main()
      {
          int** a = malloc2d(3, 3);
          int i = 0;
          int j = 0;
          
          for(i=0; i<3; i++){
              for(j=0; j<3; j++){
                  printf("%d, ", a[i][j]);
              }
              
              printf("\n");
          }
          
          free2d(a);
          
          return 0;
      }
      
posted @ 2020-09-28 14:50  nxgy  阅读(110)  评论(0编辑  收藏  举报