0

我们的代码库包含一些形式的循环while((*assignment*) *condition*),例如:

while((c = *s++) != '\0') {...}

while((i = getNext()) != NULL) {...}

不幸的是,这些导致编译器发出“条件赋值”警告,我想摆脱它。我的计划是将while循环转换for为 for( assignment ; condition ; assignment ) 形式的循环,例如:

for(c = *s++; c != '\0'; c = *s++) {...}

for(i = getNext(); i != 0; i = getNext()) {...}

这种转变有效吗?有更好的选择吗?

4

4 回答 4

4

转换是有效的,是的,但它们导致代码更难维护,因为您必须在两个地方更改分配。

我更倾向于弄清楚如何关闭该特定警告(即使它已使用诸如gcc #pragma warningpragma 之类的东西进行本地化),因为它毕竟是完全有效的 C 代码,无论是在语法上还是(在这种情况下)语义上。

于 2013-04-26T00:00:35.547 回答
1

就个人而言,我会这样写第一个循环:

for (char c; (c = *s) != '\0'; ++s)
{
    // ...
}

这清楚地表明这s是正在增加的东西。您也可以省略!= '\0'隐含的 。

我会将第二个循环保留为while循环,或者至少将赋值内部条件保留。也许像这样,以尽量减少范围污染:

for (iterator i; i = getNext(); )
{
    // ...
}

我个人认为在条件内发生部分循环活动是完全可以接受的。std::cin >> n这对于和之类的东西也是很自然的std::getline(file, line)

于 2013-04-26T00:07:15.953 回答
0

您还没有说明您的编译器是什么,但是任何质量的编译器都允许关闭此类警告。但如果你不能做到这一点:

for(;;)
{
    c = *s++;
    if (c == '\0') break;
    ...
}

是等价的并且更一般。同样地:

for(;;)
{
    i = getNext();
    if (!i) break;
    ...
}

在许多情况下,比第一个更好(但不等同)是:

for(;; s++)
{
    c = *s;
    if (c == '\0') break;
    ...
}

这些更冗长和丑陋,但它们比重复代码的转换要好得多,后者脆弱且容易出错。

于 2013-04-26T01:23:37.450 回答
0

如果我对循环的理解是正确的,那么您的转换是完全有效的,但是这种转换似乎比 while 循环更难阅读。只需在循环之前进行初始化while,然后在循环结束时递增以消除警告。

c = *s++;
while(c != '\0') 
{
    ...
    c = *s++;
}
于 2013-04-26T00:15:38.540 回答