【问题标题】:Setting #define value from method [closed]从方法设置#define值[关闭]
【发布时间】:2018-11-03 17:32:01
【问题描述】:

我正在尝试使用从文件中获取所述值的方法为我的#define 分配一个值。 我能够从文件中获取值并将其返回给 main 方法。定义能够调用它并初始化它,但是当另一个方法使用所说的定义时,我得到这个错误“初始化元素不是常数” 我尝试将方法设置为 const int 但没有成功。我该怎么做才能解决这个问题?

代码示例:

#define VALUE getValue()

int getValueFromFile(){
    File *fp;
    int value;
    if((fp = fopen("configFile.txt","rt")) != NULL){
            fscanf(fp,"value=%d\n",&value);
            fclose(fp);
            return value;
    }else{
            return -1;
}

int getValue(){
    int value;
    if((value=getValueFromFile()) != -1){
          return value;
    }else{
          return 10;
}

然后当我尝试使用它时

static unsigned long int testValue = (unsigned long int) VALUE;

我收到错误“初始化元素不是常量”


好的,所以#define 不好。我正在尝试使用全局变量,但错误现在更改为“错误:可变修改----在文件范围内” 全局变量不是静态的。 我该怎么办?

【问题讨论】:

  • 你能发布一些代码示例吗?
  • 没有任何要调试的代码,我们无法帮助调试代码。
  • 您应该显示一些代码来说明问题 - MCVE (minimal reproducible example)。但是,您只能在初始化程序中将函数调用用于自动变量,而不能用于文件范围内的变量或函数内的static
  • 花了一些时间,但这是我的问题的一些代码示例
  • 编辑后问题就很清楚了。在 C 中,您不能通过调用函数来初始化全局变量。在您的情况下,static unsigned long int testValue = (unsigned long int) VALUE;static unsigned long int testValue = (unsigned long int) getValue(); 相同

标签: c variables unix global initializer


【解决方案1】:

可能对“#define”是什么有误解。它是一个预处理器指令,这意味着在编译源代码之前,它会由预处理器进行修改,然后将其交给编译器。

就像#include 几乎从字面上复制并粘贴文本到源文件的那个位置,#define 让预处理器将标签标记为等于某些文字、宏等,并简单地替换该标签的所有实例使用给定的值。

More on preprocessor directives.

在您的情况下,预处理器值肯定不能在运行时“设置”。您可能希望在整个过程中设置和使用不是 const 的全局变量。

请记住,依赖这些(在大多数情况下)是不好的形式,并考虑需要做多少工作才能避免它。

【讨论】:

  • 我正在尝试使用全局变量,但现在错误是“错误:在文件范围内可变地修改了'array'
  • @Fabzheimer 在这一点上,问题偏离了“在运行时设置定义值”。在进行了足够的研究和努力修复新错误之后,您可能想用重现错误的代码提出一个新问题。
  • 我同意,但由于他们对我的问题投了反对票,所以我一周内不能再问其他问题了
  • @Fabzheimer 我不喜欢这样做,但是搜索该错误会返回很多结果,包括this one. 做更多的研究,你会发现太阳底下没有新鲜事。
  • 是的,我也发现了。这个问题对我来说是不同的,因为我面临的错误是由结构引起的,无论我如何定义全局变量,它都会给我这个错误:/
【解决方案2】:

在 C 中,要使用计算值而不是常量来初始化对象,可以在主例程(或在主例程启动时从主例程调用的例程)中设置它:

static unsigned long testValue;

int main(void)
{
    testValue = getValue();
    …
}

在 C 中,除了简单的“常量表达式”之外,没有其他方法可以使用计算值初始化静态对象。如果你想用一个可以在编译时计算的值来初始化一个对象(例如,sin(.01)——确定该值所需的所有信息都在运行时可用,但它需要调用一个函数),这可以通过在编译时运行程序来计算值并编写新的源代码,该源代码在编译之前合并到程序中。如果你想用一个无法在编译时计算的值来初始化一个对象,因为它只需要在运行时可用的信息,那么你必须在正在运行的程序中使用赋值,而不是编译时初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2023-03-10
    • 2013-12-08
    相关资源
    最近更新 更多