大小采取两个论点
sizeof taking two arguments
在C++IS(2003.它在C++11 IS也是(,标准指出了ISO C和C++之间的差异;即,对于
char arr[100];
sizeof(0, arr)
在 C 中返回sizeof(char*)
,但在 C++ 中返回100
。
我找不到sizeof
采取两个论点的文档。明显的后备是逗号运算符,但我不这么认为:C 中的sizeof(arr)
是100
; sizeof(0, arr)
sizeof(char*)
.sizeof(0, arr)
和sizeof(arr)
都在C++100
。
在这种情况下,我可能错过了IS的全部要点。谁能帮忙?这类似于09年讨论过的一个问题,但没有人提到IS,我认为没有给出正确的答案。
编辑:实际上,IS正在谈论逗号运算符。因此,出于某种原因,(0, arr)
在 C 中返回一个char*
,但在 C++ 中返回一个char[100]
。为什么?
在 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;
演示 : 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
.
在 C 中,数组衰减为指针,因为逗号运算符相对于右值和左值的规范不同(不是可以找到这种差异的唯一地方(。在C++数组中,数组保持为数组,产生正确的结果。
逗号运算符。而你所说的区别与sizeof
完全无关.区别实际上在于 C 语言和 C++ 语言之间的左值到右值、数组到指针以及类似的衰减行为。
C 语言在这方面相当喜欢触发:数组几乎立即衰减到指针(除了极少数特定上下文(,这就是为什么0, arr
表达式的结果具有char *
类型。它相当于0, (char *) arr
.
在C++语言数组中,它们的"数组性"保留时间要长得多。当在,
运算符数组的上下文中使用时,运算符数组不会衰减到指针(并且左值不会衰减到右值(,这就是为什么在C++中0, arr
表达式的类型仍然char[100]
。
这就是该示例中sizeof
行为差异的原因。 ?:
算子是另一个证明衰减行为差异的算子的例子,即 sizeof(0 ? arr : arr)
会在 C 和 C++ 中为您提供不同的结果。基本上,这一切都源于这样一个事实,即 C 运算符通常不会保留其操作数的左值。可以使用许多运算符来演示此行为。
sizeof
采用两个参数。 sizeof
是一个运算符,而不是一个函数。
考虑到(0, arr)
是使用逗号运算符的表达式,其他一切都到位。
了解这里可能发生的事情的最好方法是查看标准中的语法。如果我们查看 C99 标准草案部分6.5.3
一元运算符第 1 段,我们可以看到 sizeof 的语法为:
sizeof unary-expression
sizeof ( type-name )
所以第二个不适用,但在这种情况下sizeof unary-expression
如何适用?如果我们查看标准草案中的A.2.1
表达式部分并像这样完成语法:
unary-expression -> postfix-expression -> primary-expression -> ( expression )
我们得到表达式周围的括号,现在我们只需要查看逗号运算符第 6.5.17
节逗号运算符的语法,我们会看到:
expression:
assignment-expression
expression , assignment-expression
所以我们现在有:
sizeof( expression , assignment-expression )
^
|
comma operator
表达式和赋值表达式都可以将我们带到具有以下语法的初级表达式:
primary-expression:
identifier
constant
string-literal
( expression )
0
是一个常量,arr
是一个标识符,所以我们有:
sizeof( constant , identifier )
那么逗号运算符在这里做什么呢?第6.5.17
节第2段说:
逗号运算符的左操作数被计算为 void 表达式;有一个 评估后的序列点。然后计算正确的操作数;结果有其类型和值。97(
由于逗号运算符不是数组未转换为指针的例外之一,因此它会产生一个指针(这在第 6.3.2.1
Lvalues、数组和函数指示符一节中介绍(,这意味着我们最终得到:
sizeof( char * )
在C++语法非常相似,所以我们在同一个地方结束,但逗号运算符的工作方式不同。C++标准草案部分5.18
逗号运算符说:
[...]结果的类型和值是右操作数的类型和值;结果与其右操作数具有相同的值类别[...]
所以数组到指针的转换不是不需要的,所以我们最终得到:
sizeof( char[100] )
sizeof
不需要两个参数。 但它也不是函数,所以(...)
不分隔函数参数,它们只是一个语法的可选部分,并强制分组。 当你写的时候 sizeof(0, arr)
,sizeof
的参数是0,
arr
的单个表达式。 带有逗号运算符的单个表达式,用于计算逗号左侧的表达式,抛出其值(但不是其副作用(,然后计算逗号右侧的表达式,并将其值用作完整表达式的值。
我不确定 C,但这可能是语言。 在C++中,数组到指针的转换不会发生,除非这是需要的;在 C 中,如果我没记错的话,标准说它除非在某些情况下,否则总是发生。 包括作为sizeof
的运算符。 在这种情况下,由于逗号运算符没有对其操作数的类型有约束,数组到指针的转换不会在C++中进行。 在 C 中,一个逗号运算符的操作数未在异常中列出,因此确实会发生数组到指针的转换。 (在本例中,数组是逗号运算符的操作数,而不是 sizeof
的操作数。
正如一些人已经说过的,我只想补充一件事,sizeof 是一个采用表达式或强制转换表达式的运算符。出于这个原因,我养成了把偏执写成大小的习惯,只有当它是一个演员表达时。
char *arr;
struct xxx { ... } v;
我会写
sizeof arr
sizeof v
但
sizeof (struct xxx) /* Note the space after the sizeof, it's important */
sizeof (char *)
我对没有括号return
做同样的事情,因为它不是函数调用,如果我加上括号,那是因为下面的表达式需要它们。
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 将fold表达式与std::一起用于两个元组
- 如何在C++中比较两个char数组
- 给定两个偶数,求出它们之间所有偶数的平方和
- 比较两个大小不等的映射c++
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 如何在for循环中包含两个索引值的测试条件
- 在声明中合并两个常量"std::set"(不是在运行时)
- 如何使用OpenMP并行这两个循环