【问题标题】:Why does this compile with the Dev-C++ compiler and not Visual Studio's one?为什么它使用 Dev-C++ 编译器而不是 Visual Studio 编译器编译?
【发布时间】:2010-12-18 11:46:18
【问题描述】:

为什么下面的代码使用Dev-C++ 编译器和 不使用 Visual Studio?

有什么想法吗?代码如下:

#include<stdio.h>
main(){
    int n,i;
    scanf("%d",&n);
    int arr[n];
    for(i= 0 ; i <n ; i++)
    {
         //Do something with the array 
    }
    fflush(stdin);
    getchar();
}

以下是错误:

Errors http://img688.imageshack.us/img688/6618/26863513.jpg

【问题讨论】:

  • 提及你得到的编译错误将有助于我们解释它们。
  • 您的编译错误可能与行号有关。错误 3 和 4 很明显,但我看不出错误 2 是从哪里来的,还有错误 1 ​​是什么的问题。
  • 错误 2 是因为在 C89 中,所有声明都必须位于函数的顶部,然后再出现任何其他语句。 arr 必须在前面的 scanf 行之前声明。

标签: c visual-studio dev-c++


【解决方案1】:

这个:

int arr[n];

无效,因为n 不是常量表达式。您需要使用malloc 在堆上分配可变大小的数组(然后在使用free 完成后释放它们)。

如果您尝试使用 .cpp 扩展名编译它,main 的返回类型必须为 int。如果您尝试使用 .c 扩展名来编译它,那么您需要使用 c 样式的局部变量声明并在函数顶部声明所有局部变量。

【讨论】:

  • arr[n] 很可能是您的问题。 GCC(Dev-C++ 使用)初步支持 C99 变长数组,但 Visual Studio 的编译器不支持,因此编译失败。
【解决方案2】:

Visual C++ 不使用该语法进行堆栈分配(尽管我希望这样做)。您可以通过以下方式显式进行堆栈分配:

int *arr = (int *)_alloca(n*sizeof(*arr));

并且不需要释放它,因为它会在作用域结束时自动释放。

【讨论】:

    【解决方案3】:

    这不是有效的 C++ - Visual C++ 编译器确实包含最新的 C 编译器(而是 C++ 的 C 子集),特别是它没有实现 C99 或任何更新的东西。您的代码使用了 Visual C++ 编译器不知道的功能 (int arr[n])。

    【讨论】:

      【解决方案4】:

      为了简化你得到的答案:

      您的代码是 C99,Visual C++ 仅支持 C89。帮自己一个忙,获得更好的 Windows 编译器。 Intel 编译器对 C99 的支持比 Microsoft 编译器(没有)要好得多。

      【讨论】:

        【解决方案5】:

        您的计划不符合标准。

        任何符合标准的编译器都需要在尝试编译时发出诊断。

        如果 Dev-C++ 在没有警告的情况下编译它,则编译器是在不合规模式下调用的。

        除了所需的诊断之外,兼容的编译器可以尝试编译,或者直接中止编译。

        main()
        

        在 C89 中这是有效的并且不需要诊断,在 C99 中这是无效的并且需要诊断(有效的 C99 定义是 int main(void)int main(int argc, char **argv) 或等效项)......所以如果您使用的是兼容的编译器,它是一个 C89 编译器。

        scanf("%d",&n);
        int arr[n];
        

        糟糕,这在 C89 中无效。在 C89 中,您不能将代码与声明混合在一起。 C89 编译器在看到数组声明时必须发出诊断。

        所以...您正在以不符合标准的方式使用您的编译器。无法判断它为什么编译或编译失败。

        【讨论】:

        • 此外,在 C89 中,用非整数常量声明数组是无效的。在 C++ 中,使用常量整数表达式声明数组是合法的,但事实并非如此(n 的值发生在运行时),并且 Visual Studio 很可能在此处遵循 C++ 标准。
        • 是的......还有fflush(stdin);,它在标准中未定义(*),以及main()中缺少的return语句(......并且不检查返回值scanf() 在使用变量之前)。 (*) 一些编译器将刷新输入流定义为扩展
        猜你喜欢
        • 1970-01-01
        • 2014-06-07
        • 1970-01-01
        • 1970-01-01
        • 2011-10-08
        • 2011-12-30
        • 2012-02-14
        • 2015-10-31
        • 2014-04-25
        相关资源
        最近更新 更多