指针在堆上或堆栈上存储地址。经过一番搜索,我试图了解什么是“地址”;我发现它只是一个映射内存区域的整数值。
我想知道:只要一个地址只是一个整数,为什么我不能把它分配给一个整数变量:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
int a = 1024;
int* ptrA = &a;
cout << "ptrA: " << ptrA << endl; // 0018FF44
cout << "*ptrA: " << *ptrA << endl; // 1024
cout << "&a: " << &a << endl; // 0018FF44
cout << "a: " << a << endl; // 1024
// int b = ptrA; // why this is incorrect
int b = (int)ptrA; // why I need this?
cout << "b: " << std::hex << b << endl; // 18FF44
// so b is identic to ptrA!
std::cout << std::endl;
return 0;
}
答案 0 :(得分:7)
主要有两个原因。
int
可能不足以存储指针值。这是一个特定于实现的细节。在具有64位内存地址的64位平台上找到C ++实现仍然很常见,其中int
只有32位。
类型安全。编译器存在不同类型的原因之一是捕获明显的错误,例如在指向不同类的指针时使用指向一个类的指针。如果对每个对象的所有指针都只是简单的整体,那么这些错误就会被删除。
答案 1 :(得分:4)
我发现它只是一个整数值,就像内存的映射方式一样。
通常是,但这不一定是真的。
C ++标准允许许多有问题的事情,例如。变量中不用于存储值的位,无效的特定值,可能导致崩溃等,等等。指针和整数可能在这些方面有所不同。
它的一部分是常用平台上的实际问题:int
和指针可以有不同的大小(例如4和8字节)。
我想知道:只要一个地址只是一个整数,为什么我不能分配 它是一个整数变量
...这就是为什么你不能这样做的原因:不能保证在内存中分配值是可能和/或有意义的。
在类似x86的平台上,只要你使用正确的int大小,就没有真正的问题,但是C ++不仅仅是x86 ......
答案 2 :(得分:1)
您可以,但仅适用于足以容纳指针值的整数类型。在64位系统上,指针长64位,而int
通常只有32位。虽然您可以使用long int
或long long int
(取决于哪种处理器和哪种操作系统),但intptr_t
中还有inttypes.h
类型,保证能够保持指针的值。
但请注意,您几乎不必将指针的值放入整数变量。
答案 3 :(得分:0)
来自C语言标准ISO /IEC9899§6.3.2.3/ p6指针:
任何指针类型都可以转换为整数类型。除了 之前指定的,结果是实现定义的。如果 结果不能用整数类型表示,行为是 未定义。结果不必在任何值的范围内 整数类型。
正如标准所述,将指针转换为整数时存在某些问题。
考虑到上述原因,C ++作为一种强类型语言禁止这种类型的隐式转换,以避免意外行为。但是,允许在精神上进行这种明确的转换,作为程序员,你知道自己在做什么。
答案 4 :(得分:0)
类型由数据表示定义,它通过可应用于它的操作使用和。 “地址只是一个整数”是关于数据表示,而不是关于操作。地址不是整数。
答案 5 :(得分:-1)
c ++是一种强类型语言。当然,在大多数情况下,指针的地址只是整数的十六进制表示,表示存储器中的一个点。数据类型将告诉编译器需要在堆栈上保存多少空间来存储变量。指针通常是32位机器上的4个字节。
至于转换,它只是语言的制作方式。指针最初只能指向同型变量的位置。唯一的例外是无效。
对于使用强制转换的转换,上面提到的是必需的,c ++是一种强类型语言,必须知道它正在处理什么类型。