【问题标题】:a=3,2,1; gives error in gcca=3,2,1;在 gcc 中给出错误
【发布时间】:2017-03-11 14:05:24
【问题描述】:

我在 gcc 中尝试了以下代码:

#include<stdio.h>
int main()
{
    int a=3,2,1;//////////////////////ERROR!//////////////////////////
    printf("%d", a);
    return 0;
}

我预计它会成功编译为:

  • 一系列以逗号分隔的整数表达式将从左到右进行计算,最右边的表达式的值将成为逗号分隔表达式的总值。

那么,整数变量a的值应该是1吧?还是3?

当我尝试执行这个程序时为什么会出现这个错误?

错误:预期的标识符或数字常量前的“(”

【问题讨论】:

  • 不是1也不是3,是语法错误
  • 没有逗号操作符。逗号是声明的一部分。
  • @Gabriel:没有研究工作?
  • @Olaf 也许吧。但如果是这里的重点,this question 不应该有那么多赞成票(这只是一个例子)。
  • @Olaf 这甚至与我的意思相去甚远。我的观点是:研究工作量低的问题可能是一个好问题(所以我以另一个问题为例)。这里的这个问题很有趣而且写得很好,因此不值得投反对票。

标签: c gcc variable-assignment comma-operator


【解决方案1】:

如果你把初始化和声明分开,你可能会得到你所期望的:

int a;
a = 3, 2, 1;     // a == 3, see note bellow

int a;
a = (3, 2, 1);   // a == 1, the rightmost operand of 3, 2, 1

因为您的原始命令在语法上不正确(它是 声明,因此它希望声明其他变量而不是数字 21

注意:左操作数求值的所有副作用在开始右操作数求值之前完成。

所以

a = 3, 2, 1

这3个逗号运算符a = 321从左到右求值,所以第一个求值是

a = 3, 2

which 结果 2(右操作数)(顺便说一下 未分配any 变量,因为左操作数 a = 3 的值很简单3),但是在给出这个结果之前完成了左操作数的副作用a = 3,即。 e.将3 分配给变量a。 (感谢AnT的观察。)

【讨论】:

  • @J...S 至少对我来说,a=3,2,1; 导致a==3a=(3,2,1); 导致a==1。我不知道这是否是实现定义的行为。对于这两种情况,gcc 都会警告“逗号表达式的操作数无效”。我想不出这样做的实际理由。
  • @MarianD:“......得到你所期望的”?您认为OP到底期望什么?原始帖子表明 OP 希望他们的代码表现为int a = (3, 2, 1);。但是你的a = 3, 2, 1;,其实是(a = 3), 2, 1;,完全不一样。它可以编译,但行为仍然与 OP 的预期不同。
  • @MarianD 哎呀!您的代码 int a; a = 3, 2, 1;确实编译但是当我尝试 int a = 3, 2, 1;它仍然显示错误?为什么?有什么区别?
  • 比较:int a = 3, b, c(正确 - 声明 3 个变量,第一个已初始化)和 int a = 3, 2, 1(不正确 - 21 不是正确的变量名称.
  • @J...S:差异已经向您解释过了。 int a = 3, 2, 1; 按语法分组为int (a = 3), 2, 1;,(通俗地说)相当于int a = 3; int 2; int 1; 最后这些int 2; int 1; 位没有意义,这就是错误的原因。
【解决方案2】:

这被解析为一个由三部分组成的变量声明,其中包含两个无效变量。

您需要将整个初始化程序括在括号中,以便将其解析为单个表达式:

int a=(3,2,1);

【讨论】:

  • 什么时候有人用这个?
  • @OmidCompSCI:用表达式做坏事。 en.wikipedia.org/wiki/Comma_operator
  • 感谢您的链接,这很有趣,我从未见过这样使用“逗号”运算符。通常我见过的最高级的东西是带有多条件语句的 for 循环;
  • @Omid CompSCI:对于for 循环,大多数情况下它会在for 标头的第一或第三部分中使用。在条件部分使用它会很奇怪。
  • @AnT 是的,我的意思是抱歉,除了终止条件之外的所有内容。
猜你喜欢
  • 2016-03-02
  • 2019-10-19
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 2022-08-03
  • 1970-01-01
  • 2012-06-09
相关资源
最近更新 更多