Joh*_*ohn 37 c c++ arrays pointers comma-operator
在C++ IS的C.1.3(2003.它也在C++ 11 IS中),该标准指出了ISO C和C++之间的差异; 即,为
char arr[100];
Run Code Online (Sandbox Code Playgroud)
sizeof(0, arr)以C语言返回sizeof(char*),但100在C++中.
我找不到sizeof两个参数的文档.明显的后备是逗号运算符,但我不这么认为:sizeof(arr)在C中100; sizeof(0, arr)是sizeof(char*).两个sizeof(0, arr)和sizeof(arr)是100在C++中.
在这种情况下,我可能会忽略IS的重点.有人可以帮忙吗?这类似于09年讨论的问题,但没有人提到IS,我认为没有给出正确的答案.
编辑:实际上,IS正在谈论逗号运算符.因此,出于某种原因,在C中(0, arr)返回a char*,但char[100]在C++中返回a .为什么?
Naw*_*waz 48
在C中,逗号操作符不产生左值,因此该阵列arr是一个左值衰变到指针类型,是一个右值(在这种情况下).因此,由于左值到右值的转换,所以sizeof(0,arr)相当于.sizeof(char*)
但在C++中,逗号运算符会生成左值.没有左值到右值的转换.所以 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;
Run Code Online (Sandbox Code Playgroud)
演示:http://www.ideone.com/CtEhn
你可能会认为我已经通过了4个操作数,sizeof但这是错误的.sizeof操作上,结果逗号操作符.而且由于许多逗号运算符,您会看到许多操作数.
带有3个逗号运算符的4个操作数; 就像在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
Run Code Online (Sandbox Code Playgroud)
演示:http://www.ideone.com/07VNf
所以它是逗号运算符,让你觉得有很多参数.这里的逗号是一个运算符,但在函数调用中,逗号不是运算符,它只是简单的参数分隔符.
function(a,b,c,d); //here comma acts a separator, not operator.
Run Code Online (Sandbox Code Playgroud)
所以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运算符通常不保留其操作数的左值.可以使用许多运算符来演示此行为.
了解这里可能发生的情况的最佳方法是查看标准中的语法。如果我们查看 C99 标准草案6.5.3 一元运算符第1段,我们可以看到 sizeof 的语法是:
sizeof unary-expression
sizeof ( type-name )
Run Code Online (Sandbox Code Playgroud)
所以第二个不适用,但是sizeof unary-expression在这种情况下如何应用呢?如果我们查看标准草案中的A.2.1 “表达式”部分并像这样完成语法:
unary-expression -> postfix-expression -> primary-expression -> ( expression )
Run Code Online (Sandbox Code Playgroud)
我们得到了表达式周围的括号,现在我们只需查看逗号运算符部分中的逗号运算符的语法,我们就会看到:6.5.17
expression:
assignment-expression
expression , assignment-expression
Run Code Online (Sandbox Code Playgroud)
所以我们现在有:
sizeof( expression , assignment-expression )
^
|
comma operator
Run Code Online (Sandbox Code Playgroud)
表达式和赋值表达式都可以将我们带到具有以下语法的主表达式:
primary-expression:
identifier
constant
string-literal
( expression )
Run Code Online (Sandbox Code Playgroud)
0是一个常量并且arr是一个标识符,所以我们有:
sizeof( constant , identifier )
Run Code Online (Sandbox Code Playgroud)
那么逗号运算符在这里做什么呢?6.5.17第2节说:
逗号运算符的左操作数被计算为 void 表达式;评估后有一个序列点。然后计算正确的操作数;结果有其类型和值。97)
由于逗号运算符不是数组不转换为指针的例外情况之一,因此它会产生一个指针(这在第 1.5 节中介绍) 6.3.2.1 这在左值、数组和函数指示符),这意味着我们最终得到:
sizeof( char * )
Run Code Online (Sandbox Code Playgroud)
在C++中,语法非常相似,因此我们在相同的位置结束,但逗号运算符的工作方式不同。C++ 标准草案部分5.18 逗号运算符说:
[...]结果的类型和值是右操作数的类型和值;结果与其右操作数具有相同的值类别[...]
所以数组到指针的转换不是必需的,所以我们最终得到:
sizeof( char[100] )
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2333 次 |
| 最近记录: |