我应该使用 extern 吗?

问题描述 投票:0回答:3

我有以下文件:

  1. pass_args.c
  2. pass_args.h
  3. kbd.c
  4. kbd.h
  5. main.c

我需要使用 3 个全局变量:freq、amp 和 waveforms。

我是否应该使用 extern 在每个 .h 文件中声明这些变量并在其中一个 .c 文件中定义变量或创建一个 global_variable.h,在 global_variable.h 中声明这些变量并在每个 .c 中包含此 global_variable.h文件。

这是最小的可复制示例:
变化频率.c

#include "change_freq.h"

void increment_freq(double *frequency)
{
    (*frequency)++;
    if (*frequency == 1)
    {
        amp++;
    }
}

change_freq.h

#ifndef CHANGE_FREQ_H
#define CHANGE_FREQ_H

#include "global_variables.h"

void increment_freq(double *frequency);

#endif

global_variables.h

#ifndef GLOBAL_VARIABLES_H
#define GLOBAL_VARIABLES_H
double freq;
double amp;
#endif

main.c

#include "global_variables.h"
#include "change_freq.h"

int main()
{
    freq = 0;
    increment_freq(&freq);
    printf("Hello World!\n");
    printf("freq %lf\n", freq);
    printf("amp %lf\n", amp);
    return 0;
}
c global-variables extern
3个回答
1
投票

你的代码看起来几乎没问题。

这是你应该做的:

change_freq.c

#include "change_freq.h"

#include "global_variables.h"  // <<< add this line

void increment_freq(double frequency)
{
    frequency++;
    if (frequency == 1)
    {
        amp++;
    }
}

change_freq.h

#ifndef CHANGE_FREQ_H
#define CHANGE_FREQ_H

// #include "global_variables.h"  <<< remove this line

void increment_freq(double frequency);

#endif

global_variables.h

#ifndef GLOBAL_VARIABLES_H
#define GLOBAL_VARIABLES_H
extern double freq;   // << put extern here
extern double amp;
#endif

main.c

#include <stdio.h>
#include "global_variables.h"
#include "change_freq.h"

double freq;   // << define your global variables here
double amp;

int main()
{
 ...


1
投票

我需要使用的 3 个全局变量:

freq
amp
waveforms
.

  • 每个全局变量的声明应该只出现在一个

    .h
    文件中。

  • 用于这些声明的

    .h
    文件应该与变量相关。鉴于 OP 关于变量的详细信息不足,建议使用新的 .h 文件。

  • .c 文件应在需要时包含 .h。


我应该在每个 .h 文件中声明这些变量

不,只是在一个`.h文件中。

OP的代码有问题:

// global_variables.h
#ifndef GLOBAL_VARIABLES_H
#define GLOBAL_VARIABLES_H
double freq;  // The is not only a declaration, but also  a definition.
double amp;
#endif

使用

extern

// global_variables.h
#ifndef GLOBAL_VARIABLES_H
#define GLOBAL_VARIABLES_H
extern double freq;  // The is only a declaration.
extern double amp;
#endif

我应该...创建一个 global_variable.h,在 global_variable.h 中声明这些变量,并将这个 global_variable.h 包含在每个 .c 文件中。

没有。在 1 个或多个 .h 文件中声明全局变量。 (1 可能足以完成此任务)在 .c 文件中包含 need 的 .h 文件。


包括不需要的

在OP的示例代码中:

#include "global_variables.h"
不需要。

#ifndef CHANGE_FREQ_H
#define CHANGE_FREQ_H

// #include "global_variables.h"

void increment_freq(double frequency);

#endif

无法复制 OP 的“对 `increment_freq' 的未定义引用”。


0
投票

这是一个重现项目设置的脚本(在空目录中运行):

#!/bin/sh -eu
cat > global_variables.h <<EOF
#ifndef GLOBAL_VARIABLES_H
#define GLOBAL_VARIABLES_H
double freq;
double amp;
#endif
EOF

cat > change_freq.h <<EOF
#ifndef CHANGE_FREQ_H
#define CHANGE_FREQ_H

#include "global_variables.h"

void increment_freq(double *frequency);

#endif
EOF
cat > change_freq.c <<EOF
#include "change_freq.h"

void increment_freq(double *frequency)
{
    (*frequency)++;
    if (*frequency == 1)
    {
        amp++;
    }
}
EOF

cat > main.c <<EOF
#include "global_variables.h"
#include "change_freq.h"
#include <stdio.h> ///ADD!

int main()
{
    freq = 0;
    increment_freq(&freq);
    printf("Hello World!\n");
    printf("freq %lf\n", freq);
    printf("amp %lf\n", amp);
    return 0;
}
EOF

这样就可以编译运行了(

cc *.c && ./a.out
) 如果仅当您的编译器和链接器支持所谓的common variables,它允许未初始化的全局变量(
double freq; double amp;
)在多个翻译单元中暂时定义,然后链接器将它们合并。对于 gcc/clang,您可以使用
-fcommon
.

明确请求此非标准功能

便携式解决方案是做

extern double freq,amp;

在标题中 和

/*no-extern*/ double freq,amp;

在其中一个 C 文件中。

( 你看到

double freq;
double amp;
在全局范围内没有
extern
和初始值设定项都是声明和暂定定义。 暂定定义意味着你可以用初始化器重新定义它们,之后它们就完成了,或者重新暂定定义它们。如果没有给出初始化器,它们默认为零初始化,并在编译单元结束时完成。 (相当常见的)
-fcommon
扩展(也需要链接器的支持)允许您将暂定全局的概念扩展到多个翻译单元。如果我没记错的话,这是 B 的遗留功能。)

© www.soinside.com 2019 - 2024. All rights reserved.