我坐立不安地使用指针,从指针 -> 指针数组 -> 函数指针 ->指向指针的指针。.
这就是我被困住的地方...主要是复杂的语法。
假设我有一个整数数组。
int arr[4] = {1,2,3..};
我也有指针数组
int* ptr[4];
ptr[0] = arr;
这里 ptr[0] 将指向 1PTR[1] 将指向其他位置
这非常有效!
现在考虑到上面的背景,我尝试了这个。
char* crr[4] ={"C","C++","C#","F#"};
char** btr[4];
btr[0] = crr;
在 BTR 的 oth 元素中用作指针指向 crr 中的另一个指针元素。
然后我试了这个。
char* crr[4] ={"C","C++","Java","VBA"};
char** btr[4]= &crr; // Exception: cannot convert char* [4] * to char**[4]
但是当我这样做时它可以工作:O
char* crr[4] ={"C","C++","Java","VBA"};
char* (*btr)[4]= &crr;
我不明白最后两种情况。在 RHS 上使用括号请解释。
char** btr[4]= &crr; // Exception: cannot convert char* [4] * to char**[4]
这是试图从指针初始化一个数组(指针到指针),这是你不能做的。如果你想初始化第一个元素以指向crr
(如你的第一个示例),那么你会这样做
char** btr[4]= {crr};
最后一个示例是声明指向数组(指针)的指针,并从兼容的指针初始化它。
请注意,你的原始数组应该是 const char *
,而不是 char *
,因为它包含指向(常量)字符串文字的指针。
除非它是sizeof
或一元&
运算符的操作数,或者字符串文本用于初始化声明中的另一个数组,否则类型为"T
的 N 元素数组"的表达式将被转换("衰减")为"指向T
的指针"类型的表达式,并且表达式的值将是数组第一个元素的地址。
当你写的时候
btr[0] = crr;
表达式 crr
的类型为 "4 元素数组 char *
";由于它不是sizeof
或&
运算符的操作数,因此将其转换为类型"指向char *
的指针"或char **
。 这与btr[0]
的类型相匹配。
但是,当你写
char** btr[4]= &crr;
表达式 crr
是 &
运算符的操作数;因此,表达式&crr
的类型是"指向 4 元素数组的指针"char *
",或 char *(*)[4]
。
括号是必需的,因为后缀[]
运算符的优先级高于一元运算符*
运算符;表达式*a[i]
将始终解析为*(a[i])
。 因此
T *a[N]; // a is an N-element array of pointer to T
T (*a)[N]; // a is a pointer to an N-element array of T
T *(*a)[N]; // a is a pointer to an N-element array of pointer to T
指针和函数也是如此:
T *f(); // f is a function returning a pointer to T
T (*f)(); // f is a pointer to a function returning T
T *(*f)(); // f is a pointer to a function returning pointer to T
让我们看看你的定义:
-
字符大小为 4 的数组*
char* crr[4] ={"C","C++","Java","VBA"};
-
字符大小为 4 的数组**
char** btr[4]
-
指向大小为 4 的字符* 数组的指针
char* (*btr)[4]
现在您正在尝试将Array of size 4 of char*
分配给Array of size 4 of char**
并且它们属于不同的类型,因此您显然有错误。还有另一个规则(占主导地位):你不能在没有大括号的情况下初始化数组,所以数组应该用新数据初始化,而不是指向其他数组的指针。
而且您有绝对合法的指针类型Pointer to an array of size 4 of char*
可以将您的数组地址分配给