代码:
char *str[] = { "abcddsfd", "12234", "56ef111111324" };
char *(*p)[] = str;
printf("p: %x *p: %x\n", p, *p);
这里为什么 p 和*p 的值一样啊,看汇编代码都是取数组的首地址,有点迷糊编译器这么做的原因,是代码本身就有问题吗?
个人的一点理解,str 是一个数组,里面的元素都为指向字符串的指针,然后把数组的首地址传给一个指向指针数组的指针,然后后面的就迷糊了
1
kljsandjb 2019-07-03 14:22:20 +08:00 via iPhone 1
|
2
wutiantong 2019-07-03 15:35:38 +08:00
首先这代码根本就是不对的,用 C++肯定是编不过的。改成正确的样子是:
char const *str[] = { "abcddsfd", "12234", "56ef111111324" }; char const *(*p)[3] = &str; 用 C 可以编过去,但报 warning: incompatible pointer types initializing 'char *(*)[]' with an expression of type 'char *[3]' 这里 str 是个数组,但它隐式退化成了&str[0],所以代码等同于: char *(*p) [] = ( char * (*) []) ( &str[0] ); // 毕竟 C 语言允许你在不同类型的指针间瞎转。 所以 p 的值其实就是&str[0]。 当你访问*p 的时候,p 指向的地址被解释成了 char *[]类型,结果它还真是!(那里躺着个 str )。 但这也不是很重要了,毕竟你最后 printf 时,数组类型再次退化成指针,又变成了&str[0] 。。。。 |
3
wutiantong 2019-07-03 15:40:07 +08:00
把 char * 换成 int 可以减少一点障眼法:
#include <stdio.h> int main() { int arr[] = {1, 2, 3}; int *(*p) [] = arr; printf("p: %p; *p: %p", p, *p); } |
5
gaoan000 OP @wutiantong 感谢大佬,你的重点意思是不是虽然 p 和*p 数值一样,但是类型上有本质区别
|
6
wutiantong 2019-07-03 16:02:42 +08:00
@gaoan000 不是,这里重点要搞懂的是 C 语言里数组到底是个啥玩意。
|
7
gaoan000 OP |
8
wutiantong 2019-07-03 16:33:29 +08:00
@gaoan000 p 等于&arr[0] (但类型不同), *p 等同于 arr
|
9
gaoan000 OP @wutiantong 大概没刚才那么迷糊了,非常感谢
|