sizeof 运算符在 C 中接受哪些参数?

Posted

技术标签:

【中文标题】sizeof 运算符在 C 中接受哪些参数?【英文标题】:What arguments does the sizeof operator take in C? 【发布时间】:2010-12-06 03:42:34 【问题描述】:

[原标题提到'sizeof function'。]

我试过这些,它们都奏效了:

字符 *p; printf("*p 的大小为 %d\n",sizeof(*p)); //结果=1 printf("p 的大小为 %d\n",sizeof(p)); //结果=4 printf("p 的大小为 %d\n",sizeof(&p)); //结果=4

我想知道为什么第一个 printf 是 1,第二个和第三个是 4? 那么 sizeof 究竟可以接受哪些参数呢?

【问题讨论】:

【参考方案1】:

它需要一个类型。

sizeof(char) 始终为一。变量p 本身是一个指针,在你的平台上它的大小为4。然后你做&p,或者一个指向指针的指针,它的大小也为4。

在大多数现代桌面系统上,32 位架构将有 4 个字节指针,而 64 位架构将有 8 个字节指针。

sizeof 本身是一个关键字,在编译时解析,而不是一个函数。在 C99 中,数组可以是可变长度的,sizeof 会等到运行时才解析这个大小。

【讨论】:

其实我很确定当它的操作数是一个类型名时括号是必需的。 你没有修复它 - 你应该说'sizeof(char)总是一个'。您还可以将变量传递给 sizeof (然后就不需要括号了)。在大多数情况下, sizeof() 生成一个编译时常量;例外是 C99 VLA - 可变长度数组,这意味着 sizeof(arrayname) 必须在运行时计算。【参考方案2】:
sizeof (char)   = 1
sizeof (void *) = 4

第一个是 1 因为你传递的是一个字符。 (p 指向一个字符) 第 2 次和第 3 次调用收到一个 char* / void* 对象,因此它们产生 4。

【讨论】:

【参考方案3】:

因为你在 32 位机器上工作。

*p is a character == 1 byte.
p  is a pointer   == 4 bytes.
&p is an address of a pointer == 4 bytes. Same as char**

【讨论】:

【参考方案4】:

第一个答案是 char 是 1 个字节。 (取消指向实际 char 数据的指针)

第二种是说指针值是一个4字节的值,也就是内存位置用一个4字节的值来表示。

第三个是说指针的地址是一个4字节的值。

Size of 可以接受所有这些参数,并且报告所有值的准确响应。

干杯。

【讨论】:

【参考方案5】:

sizeof 不是函数,而是关键字。你可以去掉括号,它会工作得很好。因为它不是函数,所以它适用于您提供的任何类型或对象 - 它比函数灵活得多。

【讨论】:

它的信息很好,但我认为这不是他想要的 +1 表示它(通常)是编译时运算符。在 C99 中,可以在运行时使用 sizeof 来确定动态分配数组的大小。还有一种情况是不允许的:“函数”类型的表达式(例如“sizeof (main)”)。 只有在取值的大小时才能去掉括号。如果你在做sizeof(type),那么你必须有括号。 这是因为 sizeof 的有效操作数之一是“带括号的类型 ID”(另一个是对象表达式)。所以从技术上讲,您将 sizeof 应用于(type),而不是type。确实这是一个没有区别的区别,但是sizeof *p 不再是“删除括号”,就像1 + 2 是从(1) + (2)“删除括号”一样。与函数调用不同,运算符不需要括号。 如果给定 sizeof(SomeType),则必须使用括号。由于您可以将括号与变量一起使用,因此我只需使用“sizeof(whatever)”,始终使用括号;这激怒了一位坚持区分变量和类型用法至关重要的同事——我仍然认为这种区分没有价值。【参考方案6】:

sizeof 不是函数;它是一个运算符。它可以以两种方式使用:sizeof(typename)sizeof expression。与类型名称一起使用时,括号是必需的。当操作数是表达式时,不需要括号,尽管为了清楚起见,许多程序员无论如何都会给表达式加上括号。请注意,与大多数编程语言运算符不同,sizeof expression 在正常情况下评估其参数,即当其操作数不是 C99 可变长度数组时。

【讨论】:

从技术上讲,它有两种使用方式:sizeof(typename)sizeof expression。当然,如果您愿意,任何表达式都可以用括号括起来,而且这样做通常是明智的,因为没有人记得 sizeof 的优先级。 sizeof (a) ? 1 : 2 是 1,sizeof a ? 1 : 2 也是,而 sizeof (a ? 1 : 2)sizeof int 严格来说,在最新的 C 语言规范 - C99 - 'sizeof' 的参数可以计算。它在 'sizeof' 与可变长度数组 (VLA) 一起使用时进行评估。 @AndreyT:你说得对, sizeof() 可以在运行时进行评估,但仍然没有评估参数 - 只是参数的大小。这对“sizeof(1/0.0)”很重要;该表达式是一个双精度值 - 因为它没有被评估,所以也不例外。幸运的是,你不能分割数组,所以 VLA 部分不参与讨论。 好的,我已经编辑了我的答案以澄清括号问题并解决 C99 VLA。谢谢各位! 嗯,这完全取决于术语“评估”的具体含义。请注意,C99 本身在 6.5.3.4/2 中明确指出,在 VLA 的情况下,评估“sizeof”的参数:“[...]如果操作数的类型是可变长度数组类型,则评估操作数; 否则,不计算操作数[...]"【参考方案7】:

除了其他回复,请注意可能的术语混淆。

在 C 世界中,'byte' 与 'char' 相同。 IE。根据定义,每个“字符”是 1 个“字节”。 “字节”的这个含义不一定与底层硬件中的机器“字节”相关联。一个 C 的“字节”(即“字符”)可以由多个机器“字节”组成。但是,在 C 程序中,您无法访问机器字节。一切都以 C 的“字节”(即“字符”)为单位,“sizeof”给出了以“字符”为单位的大小。

由于这些原因,无论每个 'char' 实际包含多少机器字节,'sizeof(char)' 始终为 1。

【讨论】:

也就是说,一个 C 实现,其中 char 大于架构上最小的可寻址内存单元,这是非常不合时宜的,因为它会限制您在该机器上进行低级编程的选择。 【参考方案8】:

sizeof 运算符的操作数是一个类型。

如果将 sizeof 与对象或值一起使用,则会使用其类型。

sizeof 65; /* same as `sizeof (int);` */
sizeof 'X'; /* same as `sizeof (int);` */
sizeof 42.0; /* same as `sizeof (double);` */
float f;
sizeof f; /* same as `sizeof (float);` */
/* etc ... */

您可以直接为 sizeof 运算符指定类型(如上面的“相同”)。需要括号“将操作数转换为正确的类型”(如(int)2.5),而不是sizeof 本身的语法

#include <math.h>
sizeof (12 * log(100)); /* same as `sizeof (double);` */
                        /* without the parenthesis, this would be */
                        /* (sizeof 12) * log(100); */

【讨论】:

【参考方案9】:

另请注意:

sizeof 'a' == 1   // C++ 

但是

sizeof 'a' == 4   /* C */ 

(准确地说,sizeof 'a' == sizeof(int) in C as 由pmg发布)。

在 C 中,“a”在被评估之前被提升为 int。两种语言之间为数不多的不兼容问题之一。

【讨论】:

【参考方案10】:

sizeof 运算符显示我们使用的数据类型的大小。

#include <stdio.h>

int main()

    int a;
    float b;
    char c;
    double d;
    printf("%d",sizeof(a));
    printf("%d",sizeof(b));
    printf("%d",sizeof(c));
    printf("%d",sizeof(d));
 

输出:

a = 4
b = 4
c = 1 
d = 8

如果您使用的是 8 位编译器。

【讨论】:

以上是关于sizeof 运算符在 C 中接受哪些参数?的主要内容,如果未能解决你的问题,请参考以下文章

如果类具有析构函数/ delete [],则成员运算符new []的参数“size”会增加

C语言中,哪些运算符具有左结合性?哪些具有右结合性?

为啥 sizeof 被认为是运算符?

C语言中,sizeof运算符有啥作用?

C++Sizeof与Strlen的区别与联系

c ++中的sizeof运算符[重复]