请教个指针问题

2019-07-03 14:14:28 +08:00
 gaoan000

代码:

char *str[] = { "abcddsfd", "12234", "56ef111111324" };

char *(*p)[] = str;

printf("p: %x *p: %x\n", p, *p);


这里为什么 p 和*p 的值一样啊,看汇编代码都是取数组的首地址,有点迷糊编译器这么做的原因,是代码本身就有问题吗?

个人的一点理解,str 是一个数组,里面的元素都为指向字符串的指针,然后把数组的首地址传给一个指向指针数组的指针,然后后面的就迷糊了
2658 次点击
所在节点    C
9 条回复
kljsandjb
2019-07-03 14:22:20 +08:00
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] 。。。。
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);
}
gaoan000
2019-07-03 15:48:59 +08:00
@kljsandjb 谢谢指点
gaoan000
2019-07-03 15:50:15 +08:00
@wutiantong 感谢大佬,你的重点意思是不是虽然 p 和*p 数值一样,但是类型上有本质区别
wutiantong
2019-07-03 16:02:42 +08:00
@gaoan000 不是,这里重点要搞懂的是 C 语言里数组到底是个啥玩意。
gaoan000
2019-07-03 16:25:37 +08:00
@wutiantong 那这样理解呢
p 等价于 &arr[0]
*p 等价于 arr[0]
wutiantong
2019-07-03 16:33:29 +08:00
@gaoan000 p 等于&arr[0] (但类型不同), *p 等同于 arr
gaoan000
2019-07-03 16:42:28 +08:00
@wutiantong 大概没刚才那么迷糊了,非常感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/579640

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX