关于二维数组和二级指针的理解

可以参考《C语言专家编程》的第10章
、首先指针和数组有着密不可分的联系,指针变量可以当做数组来用,在用之前,应该先让指针指向一个数据块,  这个数据块                 
可以是程序中的某一个变量,
int a;
int *p = &a
int a;
int *p;
p = &a;
也可以是某一个数组
int a[3];
int *p = a;//此时a就是地址
int a[3];
int *p;
p = a;

还可以是一个新开辟的内存空间
int *p;
p = (int *)malloc(sizeof(int));
其实一级指针没有什么好说的,但是级数越高程序就越不好理解。
接下来就是二级指针和二维数组的传递关系
若char **p, a[3][2];
是否p = a;
以前我一直认为a[]是一级指针,a[][]就是二级指针,到底还是自己写程序太少。
接下来就用程序说话
#include <stdio.h>
#include <stdlib.h>

void tmp(int **aa)
{
    aa[0][0] = 10;
}

int main()
{
    int aa[3][2] = { 0 };
    tmp(aa);
    printf("%d\n", aa[0][0]);
    system("pause");
    return 0;
}
GCC上编译后出现
error: cannot convert 'int (*)[2]' to 'int**' for argument '1' to 'void tmp(int**)'
于是在翻阅网上的各种资料后发现《C语言专家编程》10.5节上有了明确的答案,
比较正常的传递多维数组的方法有3中(还有一种太复杂,想了解的可以看书)
my_function(int my_array[10][20]);

my_function(int my_array[][20]);
my_function(int (*my_array)[20]);//数组指针
my_function(int **my_array);

数组和指针参数是如何被编辑器修改的:
"数组名被改写成一个指针参数"规则并不是递归定义的。数组的数组会被改写“成数组的指针”,而不是“指针的指针”
[]的优先级高于*
                                        实参                                 所匹配的形参
数组的数组                 char c[8][10];              char(*c)[10]    数组指针
指针数组                     char *c[15];                char **c;           指针的指针
数组指针(行指针)  char (*c)[64];               char (*c)[64];   不改变
指针的指针                 char **c;                      char **c;           不改变


#include <stdio.h>
#include <stdlib.h>
void tmp(int (*aa)[2])//二维数组变成了数组指针
{
    for(int i = 0; i < 6; i++)
        for(int j = 0; j < 2; j++)
            aa[i][j] = i + j + 10;
}
int main()
{
    int aa[3][2] = { {1, 2}, {3, 4}, {5, 6} };
    tmp(aa);
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 2; j++)
            printf("aa[%d][%d] = %d\n", i, j, aa[i][j]);
    system("pause");
    return 0;
}
还有一个也是我经常使用的,但是它不是二维数组与指针之间的转化,而是用到了 数组的内存是线性连续的
#include <stdio.h>
#include <stdlib.h>
void tmp(int aa[])
{
    for(int i = 0; i < 6; i++)
        aa[i] = i;
}
int main()
{
    int aa[3][2] = { 0 };
    tmp(*aa);//将aa[3]的地址传入
    for(int i = 0; i <3; i++)
        for(int j = 0; j < 2; j++)
            printf("aa[%d][%d] = %d\n", i, j, aa[i][j]);
    system("pause");
    return 0;
}
通过VS的调试工具
关于二维数组和二级指针的理解


关于二维数组和二级指针的理解


可以看到虽然aa[3][2]的初始化都为0,但是当调用tmp(aa);子函数值还是被改变了,所以可以看到数组的内存是连续的