sizeof把两个参数
-
27-10-2019 - |
题
C.1.3C++(2003年。它在C++11得),该标准指出之间的差异C和C++;即为
char arr[100];
sizeof(0, arr)
返回 sizeof(char*)
在C,但是 100
在C++。
我找不到任何文件 sizeof
把两个参数。显而易见的后备是逗号操作者,但我不这么认为: sizeof(arr)
C是 100
; sizeof(0, arr)
是 sizeof(char*)
.既 sizeof(0, arr)
和 sizeof(arr)
都 100
在C++。
我可缺少的整个点在这一方面起到举足轻重的作用。任何人都可以帮忙吗?这是一个类似的问题讨论的后在'09,但没有一个提到的是,我不认为正确的答案。
编辑:实际上,是是在谈论的逗号操作员。因此,对于某些原因 (0, arr)
返回 char*
在C,而是一个 char[100]
在C++。为什么?
解决方案
在C语言中,由于逗号运算符与rvalues和lvalues的关系不同(不是唯一可以找到这种差异的地方),因此数组正在衰减为指针。在C ++中,数组将保留为数组,以产生正确的结果。
其他提示
在C、逗号操作员并不生产左值,因此阵列 arr
这是一个左值 衰变 进入一个指的类型,这是一个rvalue(在这种情况下)。所以 sizeof(0,arr)
变得相当于 sizeof(char*)
, 由于 左值到rvalue 转换。
但在C++、逗号操作产生的左值。有没有 左值到rvalue 转换。所以 sizeof(0,arr)
保持相同,这相当于 sizeof(char[100])
.
通过这种方式, sizeof
是不是一个功能,这是一个操作员。以下是完全有效C++(和C,如果你想像 printf
而不是的 cout
):
int a[100], b[200], c[300], d[400];
cout << sizeof(a,b,c,d) << endl;
演示: http://www.ideone.com/CtEhn
你可能会认为我已经过去了4操作数 sizeof
但这是错误的。 sizeof
工作上 结果 逗号运营。和其因为许多逗号操你看到许多操作数。
4操作数与3个逗号,经营者;就像在 1+2+3+4
, 有3个运营商、4操作数。
上述等同于以下的(有效C++0x):
auto & result = (a,b,c,d); //first all comma operators operate on the operands.
cout << sizeof (result) << endl; //sizeof operates on the result
演示: http://www.ideone.com/07VNf
所以它的 逗号 操作员,这使得你 感觉 有很多 参数.在这里, 逗号 是一个操作员,但在功能的电话, 逗号 是不是一个操作员,其简单参数的分离器。
function(a,b,c,d); //here comma acts a separator, not operator.
所以 sizeof(a,b,c,d)
工作上 类型 的结果 ,
经营者,正是以同样的方式, sizeof(1+2+3+4)
工作上 类型 的结果 +
经营者。
还注意你 不能 写 sizeof(int, char, short)
, 正是因为 逗号 操作者无法操作 类型.它的工作上 值 只。我认为, sizeof
是的只操作人员在C和C++,这可以操作 类型 为好。C++,还有一个操作者,它可操作上 类型.它的名字是 typeid
.
它是逗号运算符。您所谈论的差异与sizeof
完全无关。真正的区别在于C和C ++语言之间的从左值到右值,从数组到指针以及类似的衰减行为。
在这方面,C语言相当令人高兴:数组几乎立即衰减到指针(很少的特定上下文除外),这就是为什么0, arr
表达的结果具有char *
类型的原因。它等效于0, (char *) arr
。
在C ++语言中,数组可以使它们的“排列性”更长。当在,
运算符上下文中使用时,数组不会衰减到指针(并且左值不会衰减到rvalues),这就是为什么在C ++中,0, arr
表达式的类型仍然是char[100]
。
这就是解释该示例中sizeof
行为不同的原因。 ?:
运算符是另一个演示衰减行为相似差异的运算符示例,即,sizeof(0 ? arr : arr)
在C和C ++中将为您提供不同的结果。基本上,所有这些都源于C运算符通常不保留其操作数的左值这一事实。可以使用许多运算符来演示此行为。
这不是sizeof
的两个参数。sizeof
是运算符,而不是函数。
请考虑(0, arr)
是使用逗号运算符的表达式,其他所有内容都应放在适当的位置。
sizeof
不需要两个参数。但这也不是一个函数
因此,(...)
不会分隔函数参数,它们只是一个
语法的可选部分,并强制分组。当你写
sizeof(0, arr)
,sizeof
的参数是单表达0,
arr
。带有逗号运算符的单个表达式,用于评估
逗号左侧的表达式会抛出其值(但不是
副作用),然后计算逗号右边的表达式,
并将其值用作完整表达式的值。
我不确定C,但是这可能与
语言。在C ++中,除非进行数组到指针的转换,否则除非发生
这是必需的;在C中,如果我没记错的话,标准说
总是在某些情况下发生。包括作为
sizeof
的运算符。在这种情况下,由于逗号运算符不会
对于其操作数的类型有限制
在C ++中不会进行数组到指针的转换。在C中,
逗号运算符的运算符未在例外中列出,因此
确实发生了数组到指针的转换。 (在这种情况下,数组
是逗号运算符的操作数,而不是sizeof
的操作数。)
了解此处可能发生的事情的最好方法是查看标准中的语法。如果我们查看草稿C99标准部分的通用语言标签代码一元运算符段落 1 ,我们可以看到sizeof的语法是: 通用标签
因此第二个不适用,但是6.5.3
在这种情况下如何适用?如果我们从标准草案中查看sizeof unary-expression
Expressions 部分,并像下面这样研究语法:
通用标签
我们得到一个围绕表达式的括号,现在我们只需要从A.2.1
逗号运算符这一节中查看逗号运算符的语法,我们看到:
通用标签
所以我们现在有: 通用标签
表达式和 assignment-expression 都可以将我们带到具有以下语法的 primary-expression : 通用标签
,6.5.17
是一个常数,0
是一个标识符,所以我们有:
通用标签
那么逗号运算符在这里做什么?第 2 段的arr
段说:
逗号运算符的左操作数被评估为void表达式;有一个 评估后的顺序点。然后评估正确的操作数;结果具有其类型和值。 97)
由于逗号运算符不是数组未转换为指针的例外之一,因此它会产生一个指针(这已在部分中介绍
6.5.17
左值,数组和函数指定符),这意味着我们最终得到了: 通用标签在 C ++ 中,语法非常相似,因此我们在同一地方结束,但逗号运算符的工作方式不同。 C ++草案标准部分的
6.3.2.1
逗号运算符说:[...]结果的类型和值是右操作数的类型和值;结果与其右操作数具有相同的值类别[...] 不需要
so和数组到指针的转换,因此最终得到: 通用标签
正如几个人已经说过的,我只想添加一件事,sizeof是一个采用表达式或强制转换表达式的运算符。 出于这个原因,我习惯于将抛物线写成大小仅为 的抛物线。 通用标签
我会写 通用标签
但是 通用标签
我对return
进行了同样的操作,没有括号,因为它不是函数调用,如果加上括号,是因为后面的表达式需要它们。