243

例如: sizeof(char*)返回 4。正如 , 一样int*long long*我尝试过的所有内容。有没有例外?

4

17 回答 17

207

你得到的保证是sizeof(char) == 1。没有其他保证,包括不保证sizeof(int *) == sizeof(double *).

在实践中,指针在 16 位系统上的大小为 2(如果你能找到的话),在 32 位系统上为 4,在 64 位系统上为 8,但是依赖给定的指针并没有什么好处尺寸。

于 2008-12-29T23:11:15.810 回答
38

即使在普通的 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。

Raymond Chen在这里谈到了这一点。

于 2009-01-13T22:53:17.490 回答
31

只是已发布列表的另一个例外。在 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 位段值组成

于 2008-12-30T10:58:24.870 回答
24

如果你正在为 64 位机器编译,那么它可能是 8。

于 2008-12-29T23:04:24.420 回答
17

从技术上讲,C 标准只保证 sizeof(char) == 1,其余的取决于实现。但在现代 x86 架构(例如 Intel/AMD 芯片)上,这是相当可预测的。

您可能听说过将处理器描述为 16 位、32 位、64 位等。这通常意味着处理器使用 N 位来表示整数。由于指针存储内存地址,而内存地址是整数,因此这有效地告诉您指针将使用多少位。sizeof 通常以字节为单位,因此为 32 位处理器编译的代码将报告指针的大小为 4(32 位/每字节 8 位),而为 64 位处理器编译的代码将报告指针的大小为 8 (每字节 64 位 / 8 位)。这就是 32 位处理器的 4GB RAM 限制的来源——如果每个内存地址对应一个字节,那么要寻址更多内存,您需要大于 32 位的整数。

于 2008-12-31T04:19:54.580 回答
7

指针的大小基本上取决于实现它的系统的体系结构。例如,32 位指针的大小在 64 位机器中为 4 字节(32 位)和 8 字节(64 位)。机器中的位类型只不过是它可以拥有的内存地址。32 位机器可以有2^32地址空间,64 位机器可以有最多2^64地址空间。因此,指针(指向内存位置的变量)应该能够指向2^32 for 32 bit and 2^64 for 64 bit机器拥有的任何内存地址( )。

由于这个原因,我们看到指针的大小在 32 位机器中为 4 字节,在 64 位机器中为 8 字节。

于 2015-06-05T03:00:48.567 回答
6

除了 16/32/64 位差异之外,还可能发生更奇怪的事情。

有些机器 sizeof(int *) 将是一个值,可能是 4,但 sizeof(char *) 更大。自然寻址字而不是字节的机器必须“增加”字符指针以指定您真正想要的字的哪个部分,以便正确实现 C/C++ 标准。

现在这是非常不寻常的,因为硬件设计人员已经了解了字节寻址能力的价值。

于 2008-12-29T23:50:05.857 回答
5

大多数薄型微控制器都使用 8 位和 16 位指针。这意味着每台洗衣机、微型电脑、冰箱、旧电视,甚至汽车。

你可以说这些与现实世界的编程无关。但这是一个真实世界的例子:带有 1-2-4k ram(取决于芯片)和 2 字节指针的 Arduino。

它是最近的,便宜的,每个人都可以使用并且值得编码。

于 2013-07-16T20:23:54.320 回答
4

除了人们所说的 64 位(或其他)系统之外,还有其他类型的指针,而不是指向对象的指针。

指向成员的指针几乎可以是任何大小,具体取决于编译器如何实现它们:它们甚至不一定都是相同的大小。尝试使用指向 POD 类的成员的指针,然后使用从具有多个基类的类的基类之一继承的指向成员的指针。多么有趣。

于 2008-12-31T01:39:40.720 回答
3

据我回忆,它基于内存地址的大小。因此,在具有 32 位地址方案的系统上,sizeof 将返回 4,因为那是 4 个字节。

于 2008-12-29T23:04:52.873 回答
3

一般来说,当你在不同的平台上编译时,sizeof(几乎任何东西)都会改变。在 32 位平台上,指针的大小始终相同。在其他平台上(64 位是明显的例子),这可能会改变。

于 2008-12-29T23:06:07.130 回答
3

不,指针的大小可能因架构而异。有很多例外。

于 2008-12-29T23:17:23.333 回答
3

在 Windows 32 位机器上的 Turbo C 编译器中,指针和 int 的大小为 2 个字节。

所以指针的大小是编译器特定的。但通常大多数编译器都实现为支持 32 位机器中的 4 字节指针变量和 64 位机器中的 8 字节指针变量)。

所以指针的大小在所有机器上都不相同。

于 2014-07-14T19:04:19.980 回答
3

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.

于 2018-06-08T01:10:29.713 回答
2

指针大小为 4 字节的原因是因为您正在为 32 位架构进行编译。正如 FryGuy 指出的那样,在 64 位架构上,您会看到 8。

于 2008-12-29T23:05:18.053 回答
1

指针只是地址的容器。在 32 位机器上,您的地址范围是 32 位,因此指针始终为 4 个字节。在 64 位机器上,如果您的地址范围为 64 位,则指针将是 8 个字节。

于 2008-12-29T23:08:39.730 回答
0

只是为了完整性和历史兴趣,在 64 位世界中,对于 long 和 long long 类型的大小有不同的平台约定,分别命名为 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

来源:https ://stackoverflow.com/a/384672/48026

于 2016-08-20T15:38:13.320 回答