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进行了同样的操作,没有括号,因为它不是函数调用,如果加上括号,是因为后面的表达式需要它们。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top