为啥 sizeof 被认为是运算符?
Posted
技术标签:
【中文标题】为啥 sizeof 被认为是运算符?【英文标题】:Why is sizeof considered an operator?为什么 sizeof 被认为是运算符? 【发布时间】:2010-11-26 11:41:16 【问题描述】:为什么sizeof
被视为运算符而不是函数?
作为运营商需要具备哪些属性?
【问题讨论】:
【参考方案1】:因为 C 标准是这么说的,所以它得到了唯一的投票。
后果:
sizeof 的操作数可以是带括号的类型sizeof (int)
,而不是对象表达式。
括号是不必要的:int a; printf("%d\n", sizeof a);
完全可以。它们经常被看到,首先因为它们需要作为类型转换表达式的一部分,其次因为 sizeof 具有非常高的优先级,所以sizeof a + b
与sizeof (a+b)
不同。但它们不是 sizeof 调用的一部分,它们是操作数的一部分。
不能取 sizeof 的地址。
作为 sizeof 操作数的表达式不会在运行时计算(sizeof a++
不会修改 a)。
作为 sizeof 操作数的表达式可以具有除 void 或函数类型之外的任何类型。确实,这就是 sizeof 的意义所在。
函数在所有这些点上都会有所不同。函数和一元运算符之间可能还有其他区别,但我认为这足以说明为什么即使有理由希望 sizeof 成为函数,它也不能成为函数。
【讨论】:
哇,我就是这么想的! 我相信现在由于可变长度数组 (VLA),事情变得更加复杂。 IIRC,如果表达式中有 VLA,该标准甚至允许sizeof
产生副作用。
@glglgl 不,这没有任何意义。在这种情况下,(int)
没有什么花哨的 - 只是括号内的类型名称。这里的括号是sizeof
语法的一部分——在获取类型的大小时需要它们,但在获取表达式的大小时不需要它们。参见例如here
@anatolyg 我的评论是很久以前的了,我想我当时是想讽刺。
该标准对sizeof
使用两种表示法:sizeof unary-expression
和sizeof ( type-name )
——因此在 C11 标准中,它不被视为“强制转换”,而是带括号的类型名称。最终结果大致相同。 (作为比较,演员表表达式是( type-name ) cast-expression
。)我讨厌评论 Markdown 与 Q&A Markdown 的工作方式不同!【参考方案2】:
它可以用作编译时常量,只有当它是运算符而不是函数时才有可能。例如:
union foo
int i;
char c[sizeof(int)];
;
从语法上讲,如果它不是运算符,那么它必须是一个预处理器宏,因为函数不能将类型作为参数。这将是一个难以实现的宏,因为sizeof
可以将类型和变量都作为参数。
【讨论】:
+1 但请注意,当参数是 VLA - 可变长度数组时,它不是编译时常量。【参考方案3】:因为 C 标准是这么说的,所以它得到了唯一的投票。
而且标准可能是正确的,因为sizeof
接受一个类型并且
一般来说,如果函数的域或余域(或两者)包含比实数复杂得多的元素,则该函数称为运算符。相反,如果函数的域和余域都不包含比实数更复杂的元素,则该函数很可能被简单地称为函数。余弦等三角函数就是后一种情况的示例。
此外,当函数使用如此频繁以至于它们比通用 F(x,y,z,...) 形式发展得更快或更简单的符号时,产生的特殊形式也称为运算符。示例包括中缀运算符,例如加法“+”和除法“/”,以及后缀运算符,例如阶乘“!”。这种用法与所涉及实体的复杂性无关。
(Wikipedia)
【讨论】:
这可能解释了 C 标准(和其他编程语言)使用术语“运算符”和“函数”的动机。【参考方案4】:因为它不是函数。你可以这样使用它:
int a;
printf("%d\n", sizeof a);
函数确实有入口点、代码等。函数要在运行时运行(或内联),sizeof 必须在编译时确定。
【讨论】:
【参考方案5】:sizeof 运算符是编译时实体而不是运行时实体,不需要像函数那样的括号。编译代码时,它会在编译时将值替换为该变量的大小,但在函数执行后的函数中,我们将知道返回值。
【讨论】:
【参考方案6】:因为:
当您将值传递给函数时,对象的大小不会传递给函数,因此sizeof
“函数”将无法确定大小
在 C 中,函数只能接受一种类型的参数; sizeof() 需要接受各种不同的东西(变量和类型!你不能将类型传递给 C 中的函数)
调用函数涉及复制参数和其他不必要的开销
【讨论】:
【参考方案7】:与函数的区别很小 - sizeof 的值在编译时解析,而不是在运行时解析!
【讨论】:
VLA 除外 - 可变长度数组 - 参数。【参考方案8】:因为它是一个编译时运算符,为了计算对象的大小,它需要仅在编译时可用的类型信息。这不适用于 C++。
【讨论】:
【参考方案9】:sizeof()
运算符是编译时会发生的。可用于确定参数或自变量。
【讨论】:
【参考方案10】:Sizeof(),我认为显然它既是函数又是运算符。为什么?因为一个函数在入口阶段为入口保留了括号。但主要也是一个运算符,因为运算符是动作字符,因此 sizeof 是一个动作语句,作用于括号中的操作数。
【讨论】:
标准已经明确说明sizeof
是一个操作符以上是关于为啥 sizeof 被认为是运算符?的主要内容,如果未能解决你的问题,请参考以下文章