Answers:
您得到的保证是sizeof(char) == 1
。没有其他保证,包括没有保证sizeof(int *) == sizeof(double *)
。
在实践中,指针在16位系统(如果可以找到)上的大小为2,在32位系统上为4,在64位系统上为8,但是依靠给定的值并没有任何好处尺寸。
即使在普通的x86 32位平台上,您也可以获得各种指针大小,请尝试以下示例:
struct A {};
struct B : virtual public A {};
struct C {};
struct D : public A, public C {};
int main()
{
cout << "A:" << sizeof(void (A::*)()) << endl;
cout << "B:" << sizeof(void (B::*)()) << endl;
cout << "D:" << sizeof(void (D::*)()) << endl;
}
在Visual C ++ 2008下,对于成员函数指针,我得到4、12和8。
已发布列表的另一个例外。在32位平台上,指针可以占用6 个字节,而不是4个字节:
#include <stdio.h>
#include <stdlib.h>
int main() {
char far* ptr; // note that this is a far pointer
printf( "%d\n", sizeof( ptr));
return EXIT_SUCCESS;
}
如果使用Open Watcom编译该程序并运行它,将得到6,因为它支持的远指针由32位偏移量和16位段值组成
如果要为64位计算机进行编译,则可能为8。
sizeof(char*)==1
?你确定吗?不是size(char)==1
吗
从技术上讲,C标准仅保证sizeof(char)== 1,其余的取决于实现。但是在现代x86架构(例如Intel / AMD芯片)上,这是可以预见的。
您可能听说过处理器被描述为16位,32位,64位等。这通常意味着处理器将N位用于整数。由于指针存储内存地址,并且内存地址是整数,因此可以有效地告诉您要用于指针的位数。sizeof通常以字节为单位,因此为32位处理器编译的代码将报告指针的大小为4(每字节32位/ 8位),而对于64位处理器的代码将报告指针的大小为8 (64位/每字节8位)。这就是32位处理器4GB RAM限制的来源-如果每个内存地址对应一个字节,要寻址更多内存,您需要大于32位的整数。
除了16/32/64位差异外,甚至可能会发生更奇怪的事情。
曾经有一些机器,其中sizeof(int *)将是一个值,可能是4,但是sizeof(char *)更大。自然寻址字而不是字节的机器必须“增强”字符指针以指定您真正想要的字的哪一部分,以正确实现C / C ++标准。
现在这已经非常不寻常了,因为硬件设计人员已经了解了字节寻址能力的价值。
void*
和char*
用软件进行处理,并用一个3位的字内的偏移被增强-但是,因为没有实际上是一个64位的地址空间时,存储在高位64位的3个比特的偏移字。因此,char*
和int*
的大小相同,但是内部表示形式有所不同-并且假定指针“真正”只是整数的代码可能会严重失败。
我记得,它是基于内存地址的大小。因此,在具有32位地址方案的系统上,sizeof将返回4,因为这是4个字节。
sizeof (unsigned int) == sizeof (signed int)
,此要求位于3.9.1 / 3中。“对于每个整数类型签署的标准的,存在一个对应的(但不同)的标准的无符号整数类型:unsigned char
,unsigned short int
,unsigned int
,unsigned long int
,和unsigned long long int
,其中的每一个占据存储相同量的并具有相同的对齐要求与相应的整数类型签署 “
在Windows 32位计算机上的Turbo C编译器中,指针和int的大小为2个字节。
因此,指针的大小是编译器特定的。但通常大多数编译器都实现为在32位中支持4字节指针变量,在64位计算机中支持8字节指针变量。
因此指针的大小在所有机器上都不相同。
在Win64(Cygwin GCC 5.4)中,让我们看下面的示例:
首先,测试以下结构:
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
测试代码如下:
std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*): "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*): "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(list_node): "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*): "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(test_struc): "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*): "<<sizeof(test_struc*)<<std::endl;
输出如下:
sizeof(int): 4
sizeof(int*): 8
sizeof(double): 8
sizeof(double*): 8
sizeof(list_node): 24
sizeof(list_node*): 8
sizeof(test_struc): 2
sizeof(test_struc*): 8
您可以看到64位sizeof(pointer)
是8
。
指针只是地址的容器。在32位计算机上,您的地址范围是32位,因此指针将始终为4个字节。在64位计算机上,如果您的地址范围为64位,则指针将为8个字节。
出于完整性和历史性的考虑,在64位世界中,关于长类型和长长类型的大小存在不同的平台约定,分别称为LLP64和LP64,主要是在Unix类型的系统和Windows之间。名为ILP64的旧标准也将int = 64位宽。
Microsoft维护LLP64,其中longlong = 64位宽,但long保持在32位,以便于移植。
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64