【问题标题】:variable modified at file scope Struct C在文件范围结构 C 中修改的变量
【发布时间】:2013-10-17 08:09:18
【问题描述】:

您好,当我尝试使用用户将在命令行中输入的全局变量的数组大小分配结构时出现编译错误,然后将值传回全局声明的变量。

这里只是示例代码

#include<stdlib.h>
#include<stdio.h>

int Type;

struct list_el {
    int val;
} list1[Type];

struct list_el item;

int main() {
    Type = 10; //just sample
}

错误

在文件范围结构 C 中修改的变量

有没有办法解决这个问题?我需要它在全球范围内工作。

非常感谢。

【问题讨论】:

  • list1[Type] - 现在假设您是一名编译器,您对Type 了解多少?
  • 我真的很感兴趣这个设计试图解决的实际问题。
  • 它是我尝试制作的大程序的一部分,但 struct list_el list1[Type] 需要全局访问才能从其他函数访问

标签: c data-structures struct global-variables


【解决方案1】:

当声明一个数组时,你需要一个大小的编译时常量,Type 不需要。

如果要在运行时分配,请使用指针和malloc


嗯,实际上你可以拥有用于数组大小的非常量变量,称为variable-length arrays。使用全局变量的大小的问题是全局变量被初始化为零,所以你所做的实际上是创建一个具有零元素的数组,但前提是变量Type 在创建数组之前被初始化。

【讨论】:

  • @AlterMann 不在全局范围内。
【解决方案2】:

您的代码无效:您不能首先使用变量作为大小声明数组,然后然后分配给变量。

或者,你可以,但数组肯定不会神奇地改变。

另外,变量和数组是全局的也很奇怪。

你可能应该这样做:

int main(void)
{
  int num;

  printf("enter size:\n");
  if(scanf("%d", &num) == 1 && num > 0)
  {
    struct list_el list1[num];

    /* here, work with the array. */
  }
}

请注意,使用这样的变量是 C99 的一项功能。

【讨论】:

  • 我需要 struct list_el list1[num];全球化
【解决方案3】:

如果您希望list 及其大小Type 都是全局动态分配的,您只需这样做:动态分配。 p>

#include<stdlib.h>
#include<stdio.h>

int Type;

struct list_el {
    int val;
} *list;

int main() 
{
    Type = 10;

    list = malloc(Type * sizeof(*list));

}

也就是说,认真质疑你是否需要这些全局。如果您的编译器支持它,您可以使用局部可变长度数组 (VLA)。它是 C99 的可选功能,可通过检查 __STDC_NO_VLA__ 是否定义来进行测试。

【讨论】:

  • 所以这段代码会将类型变量 (10) 分配给 struct list_e1 数组的大小为 10,并能够全局访问该数组
  • @user1611864 这将为Type 数量的struct list_el 元素分配足够的内存,将生成的内存地址分配给指针list,然后可以将其用作list[n] 用于所有@ 987654329@ 介于 0 和分配时 Type-1 的值之间。这不会通过稍后更改Type 来神奇地增加或缩小分配的缓冲区大小。如果您愿意,请查看并了解realloc()
  • @user1611864 ...它不必是全局的。您可以使您的“其他函数”将指针和大小作为参数。我不建议在全球范围内这样做,但如果您打算这样做,这是一种方法。
  • 对于__STDC_NO_VLA__,您并不完全正确。这是 C99 的强制功能,在 C11 中成为可选功能。所以实现这个特性测试宏的编译器可能还不是很常见。
  • @JensGustedt C99 6.10.8.3 条件特性宏,“__STDC_NO_VLA__ 整数常量 1,旨在指示实现不支持可变长度数组或可变修改类型”。还是只是错误地留在标准中?
【解决方案4】:

您可以在 main 中使用 alloca() 来堆栈分配内存。

struct list_el {
  int n;
} *list;
static int Type;

int main(int argc, char** argv) {
  Type = argc;
  list = alloca(sizeof(struct list_el) * Type);

  // use list...
}

内存将保持在范围内,直到 main() 返回。我不知道atexit() 回调中会发生什么。这是一个有趣的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 2013-12-16
    • 2013-02-02
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多