【问题标题】:Understanding an odd looking C++ for loop?了解一个看起来很奇怪的 C++ for 循环?
【发布时间】:2021-02-01 15:18:16
【问题描述】:

我刚刚遇到了一些代码,我不确定为什么会这样。

请注意,这是相当老的代码,所以for (auto i : x) 不是一个选项。

代码是:

INT_PTR i,c;
for(i=0,c=m_array.GetSize();i<c;i++)
{
  // Do stuff, i & c are not changed inside the loop
}

我会在哪里做(我会使用单字母变量,但那是另一个论点:

const INT_PTR c = m_array.GetSize();
for (INT_PTR i = 0; i < c; i++)
{
  // do stuff
}

第一种方法有一些我不知道的性能优势吗?

【问题讨论】:

  • 这两种方法是相同的,唯一不同的是变量 i 的作用域
  • 我会说这里的性能“优势”是开发人员在第一种情况下输入的更少。

标签: c++ performance optimization


【解决方案1】:

我认为代码示例之间没有区别。但是,无论如何,“智能”编译器都会对此进行优化。

【讨论】:

  • 区别在于第一个i在循环外声明,第二个cconst
  • 当然,但是当编译器识别出c 从未改变时,他会像处理const 一样处理这个变量。
【解决方案2】:

曾几何时,一些编译器早已忘记了第一种方式是 C 中的唯一方式

在较旧的方言中,包括原始方言,函数的定义如下:

int foo(a, p) 
int a; 
char *p; 
{ 
}

并声明如下:

int foo(int , char ) ;
int foo2(); // unknown arguments
int foo3(void); // no arguments

必须在任何其他代码发生之前声明变量,并且它们的生命周期和可见性被延长,直到函数返回给它的调用者。前面提到的语法最初是唯一的,后来的声明被包含在for() 标头中,但变量在外部仍然可见。后来 ANSI 和 ISO 标准发生了重大变化。

在现代 C 和 C++ 中,如果 for() 不包含初始化并且没有发生迭代,则 for 循环的原始样式会导致可见的变量保持未初始化状态。它的一个优点是您甚至可以在 C++17 之前“初始化”不兼容类型的变量(引号在那里是因为从技术上讲它是赋值,而 C++ 为这些变量抛出了不同的规则):

float arr[] = { 3,4,5,6 };
int i, e;
float v;

for( i = 0, e = sizeof(arr)/sizeof(arr[0]), v = arr[i];  i < e; v = arr[++i] )
{
}

在工作中,我一看到其他程序员在 C++ 项目中使用 C 风格的函数设计,我就开始仔细检查该代码。有时他们会意外引入 UB 或不正确的行为,因为他们显然遵循 K&R C 规则。或者从某个地方抄袭了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 2018-11-07
    • 2021-03-25
    • 2015-03-20
    相关资源
    最近更新 更多