【问题标题】:C.. Array... Problems with a course assignmentC.. 数组... 课程作业的问题
【发布时间】:2020-09-29 19:21:30
【问题描述】:

所以我正在学习 C 的课程。其中一项作业是查看并理解对 5 个等级(数字)进行排序的代码。我将教授的代码复制到 MVS,但出现了错误。正如代码中的 cmets 所见,我解决的问题之一。但我不明白教授是如何编译的。

所以我的问题是:如何解决第二个错误?

int w[how_many];//error: expression must have a constant value.

有人愿意帮忙吗?

我正在使用 Visual Studio。尝试“禁用语言扩展”,将源文件从 .cpp 重命名为 .c 并更改为“编译为 C 代码 (/TC)”

#include <stdio.h>
#define SIZE 5

void print_array(int how_many, int data[], const char* str)
{
    int i;
    printf("%s", str);

    for (i = 0; i < how_many; i++)
        printf("%d\t", data[i]);
}

void merge(int a[], int b[], int c[], int how_many)
{
    int i = 0, j = 0, k = 0;

    while (i < how_many && j < how_many)
        if (a[i] < b[j])
            c[k++] = a[i++];
        else
            c[k++] = b[j++];
    while (i < how_many)
        c[k++] = a[i++];
    while (j < how_many)
        c[k++] = b[j++];

}


void mergesort(int key[], int how_many) 
{
    
    int j, k;
    int w[how_many];//error: expression must have a constant value


    for (k = 1; k < how_many; k *= 2)
    {
        for (j = 0; j < how_many - k; j += 2 * k)
            merge(key + j, key + j + k, w + j, k);
        for (j = 0; j < how_many; j++)
            key[j] = w[j];
    }
}

int main(void)
{
    //const int SIZE = 5; // removed because of error and added #define SIZE 5
    int a[SIZE] = { 67, 82, 83, 88, 99 };// error: needs constant value, solved by adding #define SIZE 5
    
    print_array(SIZE, a, "My grades\n");
    printf("\n\n");
    mergesort(a, SIZE);
    print_array(SIZE, a, "Sorted grades\n");
    printf("\n\n");
    return 0;

}

【问题讨论】:

  • Visual Studio 仅对 C(准确地说是 C89)提供有限的支持。可变长度数组是 C99 功能,Visual Studio 编译器不支持该功能
  • @UnholySheep VLA 无法初始化。
  • @AnttiHaapala 行 OP 指出给出错误不会尝试初始化数组,所以我不确定你指的是什么
  • @OP 你是说你在搬到视觉工作室之前就可以编译这个了吗?还是教授说他能编译?在我看来,他似乎故意在作业中添加错误让您解决。
  • @Spectrem - 教授能够编译。我认为他是在他的 Mac 上使用 GCC/GNU 完成的。但我不认为他故意在这个作业上犯错误。这是你看到的初学者课程。

标签: c visual-studio


【解决方案1】:

解决方案更进一步,但首先,这里的失败:

int w[how_many];//error: expression must have a constant value

是因为 MSVC 编译器不支持可变长度数组 (VLA)。 C99 和更新的 ANSI C 编译器系列支持 VLA。

所以,这里的解决方案是获得一个不同的编译器。

注意:

VS 2019 (16.8) 将包括 /std:c11/std:c17 标准 开关。见this blog post。 因为 MSVC 编译器不支持变长数组 (VLA) 它不声称符合 C99。请注意,这些开关 启用 this blog post 中介绍的新 C99 预处理器

(来自这里:Is there any option to switch between C99 and C11 C standards in Visual Studio?

所以我的问题是:如何解决第二个错误?

C99 之前,直到运行时才知道数组长度的C 程序员使用动态内存分配。在你的例子中,这个:

int w[how_many];

可以实现为:

int *w = calloc(how_many * sizeof(*w));
if(w)
{
    memset(w, 0, how_many);//zero the new memory space. (VLA needs this too)
    //use variable in code
    ...
    free(w); //always free when done, (VLA does not require)
}

编辑以解决 OP 稍后添加到帖子的内容,

const int SIZE = 5;
int a[SIZE] = { 67, 82, 83, 88, 99 };

这不是一个有效的 C VLA,因为在 C 中初始化一个 VLA 是不合法的(而且从来不是)合法的。 (不过在C++ 中是合法的)

然而这合法的:(因为 5 是一个常数值。)

#define SIZE 5
int a[SIZE] = { 67, 82, 83, 88, 99 };

【讨论】:

  • 之前也出现过同样的代码。 VLA 无法初始化。这实际上是 C++ 代码,而不是 C,或 Clang 扩展。
【解决方案2】:

回复:

所以我的问题是:如何解决第二个错误?

int w[how_many];//error: expression must have a constant value.

您可以像这样为该数组w 分配内存:

int* w = malloc(how_many * sizeof(int));

【讨论】:

    【解决方案3】:

    该代码不是正确的标准 C。

    int main(void) {
        const int SIZE = 5;
        int a[SIZE] = { 67, 82, 83, 88, 99 };
    }
    

    不是有效的 C89,因为它有一个可变长度数组。它不是有效的 C99、C11 或 C18,因为无法初始化可变长度数组

    但它是有效的 C++,因为使用 const int 指定维度的数组是静态类型的。

    另外 Clang C 编译器 编译它,但 Gnu C Compiler 理所当然地拒绝编译:

    % gcc vla.c
    vla.c: In function ‘main’:
    vla.c:49:5: error: variable-sized object may not be initialized
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |     ^~~
    vla.c:49:21: warning: excess elements in array initializer
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |                     ^~
    vla.c:49:21: note: (near initialization for ‘a’)
    vla.c:49:25: warning: excess elements in array initializer
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |                         ^~
    vla.c:49:25: note: (near initialization for ‘a’)
    vla.c:49:29: warning: excess elements in array initializer
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |                             ^~
    vla.c:49:29: note: (near initialization for ‘a’)
    vla.c:49:33: warning: excess elements in array initializer
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |                                 ^~
    vla.c:49:33: note: (near initialization for ‘a’)
    vla.c:49:37: warning: excess elements in array initializer
       49 |     int a[SIZE] = { 67, 82, 83, 88, 99 };
          |                                     ^~
    vla.c:49:37: note: (near initialization for ‘a’)
    
    % clang vla.c
    % clang vla.c -pedantic
    vla.c:49:11: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
        int a[SIZE] = { 67, 82, 83, 88, 99 };
              ^~~~
    1 warning generated.
    

    建议的解决方案:给自己找一位新教授。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 2016-02-04
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多