2012-02-20 50 views
3

我现在正在linux机器上用GCC中的sizeof()来玩弄我,我发现了一些令人惊讶的东西。C为什么指针会大于整数

printf ("\nsize of int = %lu\n", sizeof(int)); 
printf ("\nsize of int* = %lu\n", sizeof(int *)); 

产量

size of int = 4 
size of int* = 8 

我认为一个指向整数的尺寸会比实际的整数本身小得多!

我现在正在研究嵌入式软件,我的理解是,通过引用比通过价值更有效(在功耗方面)。

有人请澄清如果指针的大小大于实际值,为什么通过引用传递比通过值更有效。

谢谢!

+3

您是否在64位操作系统上运行? – 2012-02-20 18:24:23

+0

不要比较对象(或类型)的大小。根据需要使用它们。 – pmg 2012-02-20 18:31:07

+0

太棒了!我在一台64位机器上,但为什么通过引用比按值更有效? – icedTea 2012-02-20 18:31:29

回答

9

Integer可以是编译器编写者喜欢的任何大小,唯一的规则(在标准C中)是:a)int不小于一个长或大于一个长,并且b)至少有16位。

在64位平台上保持int为32位兼容性并不罕见。

+0

“你”是某人实现C,如果这不明显。 – 2012-02-20 18:29:23

+0

@JerryCoffin - 谢谢,虽然这是'新'在C99 – 2012-02-20 19:13:01

+0

@JerryCoffin - 抱歉我扫描该数字为32位。我确定它在早期的Windows上曾经是16位 - 当然是这样。 – 2012-02-20 19:21:06

2

在C中,一个指针,任何指针,只是一个内存地址。您使用的是64位机器,而在硬件级别上,内存地址是以64位值来引用的。这就是为什么64位机器可以使用比32位机器更多的内存。

+0

某个CPU的nn位代表它可以在一条指令中处理多大块数据,也称为“数据总线”。这与计算机上的大型地址无关。实际上地址总线通​​常与数据总线宽度不同。在32/64位(数据总线)PC计算机上,为了方便起见,地址总线恰好与数据总线一样大。 – Lundin 2012-02-21 13:38:40

0

http://developers.sun.com/solaris/articles/ILP32toLP64Issues.html

当转换32位程序到64位程序,仅长类型从32个比特的大小 和指针类型更改为64个比特; int类型的整数 保留32位大小。

在64位可执行文件中,指针是64位的。长整数也是64位,但整数只有32位。

在32位可执行文件中,指针,int和长整型都是32位。 32位可执行文件也支持64位“long long”整数。

+0

不是普遍适用的,也许在一个编译器或编译器生成的例子中(例如gcc 4.x)。 – 2012-02-20 18:32:19

+0

正如dwelch所示,不同的编译器使用不同的内存模型。微软使用IL32P64(32位长和64位指针),大多数Unices(显然包括Mac OS X)使用I32LP64(64位长和64位指针)。我不确定有关Windows的GCC。 – 2012-02-20 23:36:55

0

指针必须能够引用所有内存。如果(虚拟)存储器大于4吉字节左右,则指针必须大于32位。

5

当要传递的值大于参考大小时,按引用传递比传递值更有效。如果你传递的是一个大的struct/object,那么通过引用传递就很有意义。如果您想持续修改您的价值,传递参考也是有意义的。

1

有一件事与另一件事无关。一个是一个地址,一个指向某个东西的指针,如果它是一个char或者short或者int或者结构,它是无关紧要的。另一种是一种特定于语言的东西,称为int,该系统的编译器以及该版本的编译器和命令行选项恰好定义为某种大小。

看起来好像您正在64位系统上运行,所以您的指针/地址将会是64位。他们指出的是一个单独的讨论,多头可能也会是64位,有时整数,短裤可能仍然是16位,但不是硬/快速规则,并希望8位,但也不是硬/快速规则。

在这种情况下可能会变得更糟糕的是交叉编译,而在使用llvm-gcc之前,clang与现在一样稳定。对于64位主机,字节码全部是基于64位主机生成的,所以64位整数,64位指针等等,然后当你为arm目标执行后端时,它必须使用编译器库调用来完成所有这些64位工作。这些变量几乎不需要缩短整数,但是是整数。由于主机不是最终目标,-m32开关被打破,你仍然有64位整数。 gcc直接不会出现这个问题,并且clang + llvm目前也不存在这个问题。

简短的回答是语言定义了一些数据类型char,short,int,long等,并且这些数据类型具有编译器实现定义的大小。而地址只是另一种实现定义的数据类型。这就像是问为什么短的字节长度不一样?因为它们是不同的数据类型,所以一个是短的,一个是长的。一个是地址另一个是变量,两个不同的东西。

3

通过引用传递更有效,因为不需要复制数据(除指针外)。这意味着在传递具有许多字段或结构的类或任何其他大于所用系统上的指针的数据时,这样做效率更高。

在你提到的情况下,由于实际值小于指向它的指针(至少在你正在使用的机器上),所以不使用指针确实可以更高效。 请注意,在32位机器上,指针有4个字节(4 * 8 = 32位),而在64位机器上,您显然使用的指针有8个字节(8 * 8 = 64位)。

在更老的16台机器的指针也只需要2个字节,也许有一些嵌入式系统仍然采用这种架构,但我不知道这...

2

一个指向整数可以点在一个整数,但同一个指针也可以指向十,二十,一百万或一百万整数。

很明显,传递单个8字节指针代替单个4字节整数不是一个胜利;但传递一个8字节的指针来代替一百万个4字节的整数肯定是。