C语言多文件编程中全局变量的声明与定义会遇到的问题

C语言多文件编程中全局变量的声明与定义会遇到的问题

描述:

  • 在学习C语言的多文件编程的时候,看到声明全局变量竟然和声明函数一样,在.h文件中通过extern关键字声明后,还要在.c文件中"定义一次"有些不解,所以我到百度上看了些博客,那些博客对声明和定义的说法是:
    • extern int a;// 这个是声明。
    • int a;// 这个是定义。
    • int a = 10;// 这样也是定义。
  • 对于网上的声明的定义的说法,我觉得有些问题。
  • 开发工具Clion,编译工具:mingw。

1.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:

1.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
extern int a;

extern void show();

#endif /* _TEST_H */

1.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a;

void show(){
    printf("show函数\n");
}

1.1.3 main.c

#include "test.h"


int main(void) {
    a = 10;
    printf("%d",a);

    show();
    return 0;
}

1.1.4 这样能直接编译通过。

2.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:

2.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
extern int a;

extern void show();

#endif /* _TEST_H */

2.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
// int a; 这里注释掉这行代码,看看能不能编译通过。

void show(){
    printf("show函数\n");
}

1.1.3 main.c

#include "test.h"


int main(void) {
    a = 10;
    printf("%d",a);

    show();
    return 0;
}

1.1.4 这样不能直接编译通过。

  • 报了这样一个错:undefined reference to `a'
  • 意思是对“a”的未定义引用。

3.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:

3.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
// extern int a; 注释这行代码,看看能不能编译通过。

extern void show();

#endif /* _TEST_H */

3.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a; //这里去掉注释

void show(){
    printf("show函数\n");
}

3.1.3 main.c

#include "test.h"

int main(void) {
    a = 10;
    printf("%d",a);

    show();
    return 0;
}

3.1.4 这样开发工具直接报错,也不能编译通过。

  • 开发工具报错:Use of undeclared identifier 'a'。
  • 意思是:使用未定义的标识符 'a'。
  • 编译报错:error: 'a' undeclared (first use in this function)。
  • 大致意思是:'a' 在main函数第一次使用时,没有定义。

4.创建3个文件,分别是main.c、test.h、test.c,具体代码如下:

4.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
extern int a; // 这次,有无这行代码都不会报错。

extern void show();

#endif /* _TEST_H */

4.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a; 

void show(){
    a = 10;
    printf("%d\n",a);
    printf("show函数\n");
}

4.1.3 main.c

#include "test.h"

int main(void) {
    show();
    return 0;
}

4.1.4 这样能直接编译通过。

4.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:

4.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
extern int a; // 去掉注释

extern void show();
extern void show2();

#endif /* _TEST_H */

4.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a; //这里去掉注释

void show(){
    printf("show函数\n");
}

4.1.3 test.h

#include "test.h"

int a;

void show2(){
    printf("test2.h");
}

4.1.4 main.c

#include "test.h"

int main(void) {
    a = 10;
    printf("%d",a);

    show();
    show2();
    return 0;
}

4.1.5 这样能直接编译通过。

  • 这次,在test.c和test2.c中,都有“ int a; ”这行代码,没有对a进行赋值操作,在main函数中才进制赋值操作。

5.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:

5.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
extern int a; // 去掉注释

extern void show();
extern void show2();

#endif /* _TEST_H */

5.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a = 10; //这里去掉注释

void show(){
    printf("show函数\n");
}

5.1.3 test.h

#include "test.h"

int a = 20;

void show2(){
    printf("test2.h");
}

5.1.4 main.c

#include "test.h"

int main(void) {
    a = 10;
    printf("%d",a);

    show();
    show2();
    return 0;
}

5.1.5 这次不能直接编译通过。

  • 这次,在test.c和test2.c中,int a 后面加上赋值操作。
  • 这次编译报错: multiple definition of `a'。
  • 意思是:多次定义 ' a '。

6.创建4个文件,分别是main.c、test.h、test.c、test2.c 具体代码如下:

6.1.1 test.h

#ifndef _TEST_H
#define _TEST_H

#include <stdio.h>

// 声明全局变量
// extern int a; // 注释这行代码

extern void show();
extern void show2();

#endif /* _TEST_H */

6.1.2 test.h

#include "test.h"

// 这句代码的具体是声明还是定义?
int a; 

void show(){
    a = 10;
    printf("%d\n",a);
    printf("show函数\n");
}

6.1.3 test.h

#include "test.h"

int a;

void show2(){
    a = 20;
    printf("%d\n",a);
    printf("test2.h");
}

6.1.4 main.c

#include "test.h"

int main(void) {
    show();
    show2();
    return 0;
}

5.1.5 这次能直接编译通过。

  • 这次 a 没有在.h文件中声明。
  • 这次在test.c和test2.c文件中,都对a进行定义且赋值操作。

总结:

  • 1.1 在多文件编程中,如果在.h文件中,通过extern关键字声明了某个全局变量(这里假定为:a),其他.c文件如果想使用这个变量的话,必须定义一次(也就是没有赋值的定义,类似:int a;)
  • 1.2 且无论多少个.c文件导入了该头文件,都可以定义一次该变量,但有个前提,该变量都不能在函数体外赋值。
  • 2.1 在多文件编程中,如果 没有 在.h文件中,通过extern关键字声明了某个全局变量(这里假定为:a),只要 不同时 在定义的时候不赋予初始值,那么都可以定义(类似:int a;)。(赋值方式:在函数中赋值)。
  • 2.2 在不同的.c文件中,定义相同的全局变量(假定为a),他们的地址都相同。
  • 后续会查询资料更新这个博客。
posted @ 2023-08-18 19:41  wbnyua  阅读(186)  评论(0编辑  收藏  举报