【问题标题】:How to execute a part of code inside a function only once using #ifndef?如何使用#ifndef 只执行一次函数内的部分代码?
【发布时间】:2017-10-13 15:19:56
【问题描述】:
//static int initialized;
void print(struct student *arg) {
  #ifndef first_call
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  #endif
  ...
}

我只想在 if 块中执行代码行一次。

我当然知道如何通过不同的方式做到这一点(评论部分)。

但我想知道为什么我的代码不能按预期工作。

谢谢。

【问题讨论】:

  • 你不能使用预处理指令来做到这一点!
  • #ifndef 等...是预处理器指令,因此仅在编译期间发生,而不是在执行期间发生。
  • 您不想为此使用条件编译。使用简单的if 语句和全局或静态变量。
  • #ifdef 和 #ifndef 是预处理器指令,在运行程序时不计算,而是在编译之前计算。
  • 感谢您的回答。但我在en.cppreference.com/w/c/preprocessor/conditional看到了类似的代码

标签: c ifndef


【解决方案1】:

编译期间会发生预处理指令。意思是,在你的程序运行之前,它需要:

//static int initialized;
void print(struct student *arg) {
  #ifndef first_call
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  #endif
  ...
}

然后把它变成:

//static int initialized;
void print(struct student *arg) {
  #define first_call 1
  //if (!initialized) {
    //initialized = 1;
    printf("sizeof(*arg1): %lu\n", sizeof(*arg));
  //}
  ...
}

这意味着,您的意图不会发生。您只需将 first_call 定义为 1。

initialized 这样的临时变量是让它运行一次的好方法。但请记住,退出此函数调用后,局部变量会被销毁。提示:查找 静态变量..

这可行:

void print(struct student *arg) 
{
    static bool initialized = false;
    if (!initialized) 
    {
        initialized = true;
        printf("sizeof(*arg1): %lu\n", sizeof(*arg));
    }

    ...
}

【讨论】:

  • 哦,谢谢莱基。你说预处理器在编译之前执行一次,所以#ifndef ... #endif 变成了#define。对吗?
  • 但我认为 cppreference 也是正确的。有很多#ifdef。
  • 在编译之前,这些指令被处理。含义...它检查#ifndef 或#ifdef 和“如果未定义”之类的条件,它会按照您说的去做,并在#endif 处结束“要做什么”。编译前。预处理器指令处理完毕后,编译代码。
  • 大声笑,我说 cppreference 是对的。他们正在解释指令是如何工作的,就像我一样。但你的问题是你是否可以使用#ifndef 让代码只运行一次,答案是否定的。
  • 感谢您的补充说明。我混淆了你对我简短英语的含义。祝你有美好的一天!
【解决方案2】:

你走错路了。 #ifdef 是预处理器命令,在编译器之前 被解析。这意味着如果不满足条件,则在编译之前简单地删除 #ifdef 块中的所有内容。

对于您的特定问题,使用静态变量的常用方法之一:

int my_func()
{
    static int initialized = 0;

    if (!initialized)
    {
        /* Initialize */
        ...

        initialized = 1;
    }

    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多