将数组称为指针

我似乎无法理解数组或2d数组上的不同声明之间的区别。
例如:

void swap(char **a, char **b) { char *t = *a; *a = *b; *b = t; } int main(int argc, char **argv) { char a[] = "asher"; char b[] = "saban"; swap(&a,&b); } 

这段代码没有编译,它输出:

 warning: passing argument 1 of 'swap' from incompatible pointer type test.c:10: note: expected 'char **' but argument is of type 'char (*)[6]' 

不是指向char数组的第一个单元格的指针而且&a是指向指针的指针?

另一个例子是:

 char (*c)[3]; char (*d)[3]; swap(c,d); 

不编译..是char (*c)[3]与指向char a[] = "ab"的指针相同?

但是这确实编译:

 char *c[3]; char *d[3]; swap(c,d); 

所以我完全糊涂了。 为什么会有区别? 关于这个问题是否有一些规则可以防止我一直误解?

谢谢你们

我认为这是你困惑的根源。

数组变量是固定对象。 它指的是一组固定的数组成员。 尽管数组成员的值可以,但它无法更改。

在所有表达式上下文中,除了作为一元& (地址)和数组sizeof的参数之外,它将衰变为指向其第一个元素的指针。

鉴于:

 char a[] = "asher"; 

表达式a将衰减为指向char( char* )的指针,并指向a的第一个字符。

表达式&a是指向char( char (*)[] )数组的指针。 它是指向完整数组的指针,而不是指向第一个字符的指针。 它是指向数组第一个字符的指针的不同类型,尽管它与指向数组第一个字符的指针具有相同的值。

但是,表达式a&a都不是值,它们是临时指针值。

你不能交换数组,你只能交换指针,但要做到这一点,你需要左值指针,你可以采取其地址。

 void swap(char **a, char **b); int main(int argc, char **argv) { char a[] = "asher"; char b[] = "saban"; char* pa = a; char* pb = b; swap(&pa, &pb); }