【问题标题】:The equivalent C code of a valid C++ code with a While loop does not compile带有 While 循环的有效 C++ 代码的等效 C 代码无法编译
【发布时间】:2015-07-20 18:41:33
【问题描述】:

以下包含 while 循环的代码在 C++ 中编译。

#include <iostream>
using namespace std;

int main() {
    while (int i = 5)
    {
        break;
    }
    return 0;
}

但是,如果在 C 中编译,以下等效 C 代码会导致错误:

#include <stdio.h>

int main() {
    while (int i = 5)
    {
        break;
    }
    return 0;
}

编译器输出:

> prog.c: In function 'main': prog.c:5:9: error: expected expression
> before 'int'   while (int i = 5)prog.c: In function 'main':
> prog.c:5:9: error: expected expression before 'int'   while (int i =
> 5)

为什么会这样?我试图在 C 中查找 while 循环的文档,但也找不到。

【问题讨论】:

  • Valid C++ code does not compile in C 而且,那又怎样?有无数有效的 C++ 代码示例无法在 C 中编译。
  • 我认为你不应该对这个问题投反对票。 C 和 C++ 通常混为一谈,因此您会混淆它们的特性是可以理解的。可能没有人再研究C了,但是如果你熟悉C++,用不了一个小时就可以理解C子集是什么。
  • @PaulMcKenzie 如果您喜欢更好的标题,请继续更改它。别再恶心了!
  • @wallyk 感谢您的“支持”,如果您已经这样做了。
  • @lifebalance 我的评论是在您编辑问题以添加 C 代码之前发表的。如果您最初说“我有这个 C++ 代码,但我知道它不会编译为 C 代码,所以我在 C 中做了这个并且遇到了问题”,那么这将比您最初的未经编辑的帖子更有意义。

标签: c++ c while-loop syntax-error


【解决方案1】:

C 和 C++ 是不同的语言。 &lt;iostream&gt; 不是 C 库的一部分,usingnamespace 只是 C++ 关键字。不要混用这些语言,因为它们根本不一样。

另外,正如@sasquatch 所提到的,在 C 中在 while 条件中声明变量是非法的。

您不应该期望 C++ 代码在 C 中编译。您也不应该期望反过来,因为 C 不是 C++ 的正确子集。

【讨论】:

  • 我的意思是用 C 编写“等效”代码。将适当地更新问题。
  • @lifebalance 在这种情况下,这只是while 的问题。无论如何,还有许多其他区别,例如,int* p = malloc(...) 在 C 中工作(它是 the recommended way of doing it),但需要在 C++ 等中进行转换。
  • 如果for 循环允许在C 中初始化变量,为什么不在while 循环中也允许呢?
  • 无论如何,我为 while 循环添加了指向 C++ 和 C 语言文档的链接作为单独的答案。
  • @lifebalance: C 只允许在for 语句的第 1 条中声明。 while 循环中的表达式类似于 for 语句的控制表达式 (expression-2),其中声明不合法,甚至没有意义,因为需要表达式的值而声明没有价值。
【解决方案2】:

C++ 中,condition 会在 while 循环的每次迭代之前进行测试。逐字逐句来自C++ reference

condition - 任何上下文可转换为的表达式 booldeclaration 带有大括号或等号的单个变量 初始化器。此表达式在每次迭代之前进行评估,并且 如果它产生假,则退出循环。如果这是一个声明, 初始化器在每次迭代之前进行评估,如果 声明的变量转换为false,循环退出。

而在 C 中,expression 会在 while 循环的每次迭代之前进行测试。逐字逐句来自C reference

expression - scalar 类型的任何表达式。这个表达式是 在每次迭代之前进行评估,如果比较等于zero, 循环退出。

【讨论】:

    【解决方案3】:

    在 C 中,while 需要括号内的表达式。你所拥有的是变量的声明。您必须在循环之前声明变量,然后将表达式编写为 i == 5 以在 C 中编译。

    This 帖子更详细地介绍了 C 与 C++ 相比的期望。他们为 if 解释的相同规则也适用于一段时间。

    【讨论】:

    • 在问这个问题之前,我确实参考了那个 SO 帖子。同时,找到了指向while 循环的语言文档的链接,这阐明了差异。请参考下面我的回答。
    【解决方案4】:

    C++和C中while语句的定义有所不同。

    在 C++ 中,while 语句的定义方式如下

    while ( condition ) statement
    

    条件又被定义为

    condition:
    expression
    attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
    attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
    

    正如您所见,除了表达式之外,条件可能是带有一些初始化程序的声明。 ibitializer 的值被转换为bool 类型的表达式,并根据布尔值执行while 语句。

    所以在你的 C++ 程序中,while 语句条件下声明的初始化器的值等于 5

    while (int i = 5)
    

    因为它不等于零,所以它被转换为布尔值true

    在 C 中,while 语句定义如下

    while ( expression ) statement
    

    如您所见,此处明确指定只能使用表达式。 C 不允许在 while 语句中使用声明。所以这个说法

    while (int i = 5)
    

    不会在 C 中编译。

    这不是C++和C的唯一区别,比如下面这个条件运算符会用C++编译,不会用C编译

    int x = 10;
    int y = 20;
    
    ( x < y ? x : y ) = 20;
    

    或者这条语句会用C++编译,不会用C编译

    int x;
    int y = 20;
    
    ++( x = y );
    

    下面的代码 sn-p 在 C++ 和 C 中会产生不同的结果

    if ( sizeof( 'A' ) == 1 ) puts( "They are equal" );
    else puts( 'They are not equal" );
    

    或者考虑下面的例子

    int x = 10;
    void *vp = &x;
    int *ip;
    
    ip = vp;
    

    这段代码sn-p会用C编译,不会用C++编译。所以你应该小心。

    此外,C 和 C++ 甚至具有不同的基本类型。例如,在 C 中有整数类型 _Bool 在 C++ 中不存在。另一方面,在 C++ 中有类型 bool 和相应的布尔文字 falsetrue 在 C 中不存在。在 C++ 中有指针文字 nullptr 在 C 中不存在。或者在 C 中有复合文字在 C++ 中不存在。或者在 C++ 中存在基于范围的 for 语句,而 C 等中不存在。:)

    【讨论】:

      【解决方案5】:

      您上面的代码存在多个问题。

      首先,您可能希望摆脱名称空间和标题。它们甚至没有在代码中使用,也无法被 c 编译器读取。

      其次,您不能在任何循环命令中定义变量类型。例如 while (int i != 5) 和 for (int i =0 ...) 在 c 中是无效的。您必须在循环之前定义变量。

      最后,虽然我相信 c++ 标准允许您在 while 语句中定义变量,但我强烈建议不要这样做。将比较语句与变量定义混合在一起有点令人困惑,即:int x、bool y、double z 等。

      【讨论】:

      • 你是对的,并且支持你的观点,这里有一个示例代码 - ideone.com/rn379R - 我仍然好奇在什么条件下声明实际上会派上用场。
      • @lifebalance 该代码完全符合我的观点。谢谢你。我也很好奇是否存在在 while 语句中声明有意义的情况。
      • ideone.com/z1LYRl - 它几乎是 C 代码,但在 C++ 中编译,并在 while 范围内声明了 nextstackoverflow.com/q/190748/307454 上关于同一主题的一些更有趣的回复
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2011-03-10
      • 2021-06-05
      • 2015-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多