【问题标题】:Incrementing variable used as array index in function call [duplicate]在函数调用中用作数组索引的递增变量[重复]
【发布时间】:2014-01-23 14:24:07
【问题描述】:

在 C 中,这符合我的预期

void foo(int a, int b ) { printf("%i,%i ",a,b ); }

int main()
{
  int i=1;
  foo(i++,i);
  foo(i++,i);
  foo(i++,i);
  foo(i++,i);
  return(0);
}

输出:1,2 2,3 3,4 4,5

现在,正如我所猜测的那样,以下内容不起作用: void foo(int a, int b) { printf("%i,%i",a,b); }

int main()
{
  int a[] = { 100,200,300,400,500,600,700 };
  int i=0;
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  foo(a[i++],a[i]);
  return(0);
}

返回 100,100 200,200 300,300 400,400

按照上一个示例的逻辑,我本来期望 100,200 200,300 300,400 400,500

我的第一个怀疑是增量仅在函数调用之后调用,但是,正如第一个示例所示,i 确实在函数调用内部递增,除非它用作数组的索引。

我也尝试过使用 foo(*(a+(sizeof(int)i++)),(a+(sizeof(int)*i)));只是为了检查,它也像第二个例子一样。

编译器是gcc 4.6.3版

我的问题是,为什么当我将变量 i 直接用作函数参数时它会起作用,而当我将变量 i 用作用作函数参数的数组的索引时却不起作用?

【问题讨论】:

  • 这不仅是重复的,而且问题来了,为什么人们要写这么粗鲁的代码? foo(a[i], a[i+1]); i++; 有什么不好?
  • @JensGustedt:他们编写这样的代码是因为他们对 C 的工作方式有不同的心智模型。在他们的模型中,参数完全按照写入的顺序进行评估,并且 foo(i++, i) 是完全定义的。实际的 C 模型违反了两个正常的人类习惯:评估顺序与阅读文本的顺序不同,并且评估顺序不是唯一确定的。因为这些特性对于一些学习者来说是不熟悉的,所以必须教授它们。后一个属性也是抽象的,因此更难举例说明。
  • @JensGustedt for( i= 0; i

标签: c arrays gcc


【解决方案1】:

您的两个代码都调用undefined behavior。您可能会得到预期或意外的结果。
使用 -Wall 标志编译您的代码。编译器应该给出警告:

[Warning] operation on 'i' may be undefined [-Wsequence-point]  

阅读C_FAQ - 3.8。它很好地解释了这个问题。

【讨论】:

  • 有时很难忘记 C 并不完美。
猜你喜欢
  • 2011-01-01
  • 2019-04-08
  • 2019-06-09
  • 2015-10-25
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
相关资源
最近更新 更多