为什么这是有效的:
int a = 5;
int *aPtr = &a;
printf("%i", *aPtr);
但这不是:
int a = 5;
int aPtr = &a;
printf("%i", *aPtr);
我不是在寻找它抛出的错误。我试图理解为什么这在概念上不起作用。
最佳答案
int aPtr = &a;
声明一个名为 aPtr
的对象类型为int
,所以它不是一个指针。
更糟糕的是,sizeof(int) != sizeof(int *)
在几个常见平台上(例如,自 Windows XP 以来的所有 x64 版本的 Windows),因此您会丢失指针包含的一些信息,可能会导致存储的值变得无用。
但是,假设它有效,aPtr
仍然是 int
类型的对象,因此不能使用指针间接来获取存储在 aPtr
中的地址处的值。 ,表示表达式 *aPtr
不会编译。没有什么可以阻止您类型转换 aPtr
正确的指针类型:
int a = 5;
int aPtr = &a;
printf("%i", *(int *)aPtr);
同样,这是假设 aPtr
存储 a
的完整地址。不管怎样,这只是 C 的类型安全在起作用,这是一件好事(参见上面的 sizeof(int) != sizeof(int *)
段落)。
如果“概念上”你的意思是“假设地址正确存储在 aPtr
中”,那么除了它不是有效的 C 之外,你的代码没有任何问题,如上面的转换示例所示。如果地址是0x80,你甚至可以将它存储在一个很小的unsigned char
中。如果你愿意的话可以反对。它存储在内存中的该地址,无论 C 通过拒绝编译语法上无效的代码来阻止您使用它。当然,使用正确的变量类型要容易得多,而不是与编译器对抗并进行强制转换。
那么,您可能会问,“如果 &a
存储在 aPtr
中,为什么编译器不能识别并简单地理解 *aPtr
与 *&a
的含义相同?”如果这是问题所在,那么答案很简单:一旦您存储 &a
在某种类型的对象中T
,编译器理解对象用于存储 T
类型的值就这样。它不知道它包含内存地址,无论您是否在该对象中存储了内存地址;它只知道有一个 T
类型的值储存在里面。再说一遍,这只是 C 的类型系统按预期工作。
关于c - 为什么需要在 C 中用 * 定义对指针的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50072503/