C语言关键字之extern

本文详细解析了C语言中extern关键字的使用方法,包括如何声明全局变量和函数,以及在不同文件间共享这些资源的具体实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.extern对变量的声明

1.1在头文件中声明为全局变量

1.2在main.c文件中调用变量a之前将a声明为全局变量

1.3定义时直接声明为全局变量

2.extern对函数的声明

2.1在头文件中声明为全局函数

2.2在.c文件中调用之前将函数声明为全局函数

2.3定义时直接声明为全局变量

总结:


extern译为“外面的,外部的”,在C语言中用来声明一个变量为外部变量,也叫全局变量;或者声明一个函数在外部进行了定义。也就是说,用extern修饰的变量或函数在同一工程下的其他文件也可以进行调用。

下面用具体的例子说明extern的用法。

1.extern对变量的声明

假设在test.c文件中定义了一个变量a,如果在mian.c文件中想调用它,那么有三种方式:①将变量a在test.h头文件中声明为全局变量;②在main.c文件中调用变量a之前将a声明为全局变量;③变量a在test.c定义时直接声明为全局变量。

1.1在头文件中声明为全局变量

test.h

#ifndef __TEST_H__
#define __TEST_H__

extern a;//声明变量在外部进行了定义

#endif

test.c

#include <stdio.h>
#include "test.h"

int a=10;//定义变量,并进行赋值

mian.c

#include <stdio.h>
#include "test.h"//一定要包含头文件才可以使用全局变量a

int main()
{
    printf("a=%d \r\n",a);//在test.c中定义过,并赋值为10,此处应该输出10
    a=20;
    printf("a=%d \r\n",a);//重新赋值,应该输出20
}

输出结果:

1.2在main.c文件中调用变量a之前将a声明为全局变量

test.c

#include <stdio.h>
//#include "test.h"//将.h文件屏蔽掉

int a=10;//定义变量,并进行赋值

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉头文件

extern int a;//声明外部变量

int main()
{
    printf("a=%d \r\n",a);//在test.c中定义过,并赋值为10,此处应该输出10
    a=20;
    printf("a=%d \r\n",a);//重新赋值,应该输出20
}

输出结果:

两种方法从结果看都对,事实上,两种方法本质是一样的,第一种main.c包含了test.h头文件,而test.h头文件中进行了外部声明,也就相当于间接在main.c中进行了外部声明;第二种直接在main.c中进行了声明。

1.3定义时直接声明为全局变量

test.c

#include <stdio.h>
//#include "test.h"//将.h文件屏蔽掉

extern int a=10;//定义变量,并进行赋值,并声明为全局变量

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉头文件
//extern int a;//屏蔽掉,不做外部声明

int main()
{
    printf("a=%d \r\n",a);//在test.c中定义过,并赋值为10,此处应该输出10
    a=20;
    printf("a=%d \r\n",a);//重新赋值,应该输出20
}

输出结果:

以上三种方式都可以正确定义声明一个全局变量。但是注意,①像第3中方法这种定义时直接声明的情况只能用在.c文件中,不能用在.h头文件中,否则编译会报错;②不可以只在.h头文件声明外部变量,而在外部.c文件中不对变量进行定义,这样也会报错;③不可以在.h头文件中进行定义变量,.h头文件只能进行声明。

2.extern对函数的声明

假设在test.c文件中定义了一个求和函数sum(int a,int b),如果在mian.c文件中想调用它,那么有两种方式:①将求和函数sum(int a,int b)在test.h头文件中声明为全局变量;②在main.c文件中调用求和函数sum(int a,int b)之前将求和函数sum(int a,int b)声明为全局变量;③求和函数sum(int a,int b)在test.c定义时直接声明为全局变量。

2.1在头文件中声明为全局函数

test.h

#ifndef __TEST_H__
#define __TEST_H__

extern int sum(int a,int b);//声明函数在外部进行了定义

#endif

test.c

#include <stdio.h>
#include "test.h"

int sum(int a,int b)//求和函数,返回a+b之和
{
    return a+b;
}

mian.c

#include <stdio.h>
#include "test.h"//加载头文件

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//应该输出30
}

输出结果:

事实上,在.h文件中声明函数时,不用加extern也行,只要调用此函数的.c文件包含test.h头文件即可。

2.2在.c文件中调用之前将函数声明为全局函数

test.c

#include <stdio.h>
//#include "test.h"//将.h文件屏蔽掉

int sum(int a,int b)
{
    return a+b;
}

main.c

#include <stdio.h>
//#include "test.h"//屏蔽掉头文件

extern int sum(int a,int b);//在调用之前声明外部函数

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//应该输出30
}

输出结果:

2.3定义时直接声明为全局变量

test.c

#include <stdio.h>
//#include "test.h"//将.h文件屏蔽掉

extern int sum(int a,int b)//直接声明为外部函数
{
    return a+b;
}

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉头文件

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//应该输出30
}

输出结果:

以上三种方法可以正确声明定义一个外部函数。事实上,我在使用VS2010编译时,在test.c文件中对求和函数不用extern进行外部声明,在test.h文件中也不做声明,也是可以编译运行成功的,但是会出现警告,如下图:

总结:

为了避免可能的错误,大家还是规范些代码比较好。一般对于全局变量和函数采用1.1和2.1的方式,这样代码层次清晰,方便理解和调试

欢迎大家在评论区讨论。

<think>好的,我现在要帮助用户理解C语言中的extern关键字。首先,我需要回忆一下extern的基本概念。根据引用[1]和[3],extern主要用于声明外部变量或函数,告诉编译器这个符号在其他源文件中定义,这样当前文件就可以引用它而不会重复定义。 接下来,我应该整理extern的主要作用。引用[3]提到三点:避免重复定义、声明外部符号和增加可扩展性。这几点很重要,需要详细解释。比如,当多个文件需要共享同一个变量时,用extern可以避免在每个文件都定义一次,从而防止链接错误。 然后,使用场景。用户可能想知道在什么情况下需要使用extern。比如,多文件编程中全局变量的共享,或者函数的跨文件调用。这里可以举例子,比如在file1.c中定义全局变量,在file2.c中用extern声明它,这样两个文件就能共享这个变量了。引用[2]中的示例代码展示了如何在test.c中通过extern声明Add函数,即使它的定义在另一个文件里。 还要注意extern的不同用法。对于变量,需要在声明时加上extern,而定义时不加。对于函数,虽然函数默认是extern的,但显式声明可以增强可读性。此外,头文件的使用也是一个常见场景,通过头文件声明extern变量,然后在源文件中包含,这样方便管理。 可能用户会有疑问,比如extern和static的区别。根据引用[2],static限制作用域在当前文件,而extern则扩展作用域到其他文件。这时候需要解释两者的对比,帮助用户更好理解。 另外,需要注意extern的使用注意事项。比如,不能同时用extern和初始化,否则会变成定义,导致重复定义错误。比如extern int a = 5; 是错误的,应该只在定义时初始化。 最后,生成相关问题的时候,要涵盖extern的作用、使用场景、与static的区别,以及常见错误。这样用户可以有进一步的学习方向。 总结一下,回答的结构应该是先介绍extern的作用,再分点详细说明,然后给出使用场景和示例代码,最后注意事项和相关问题。确保引用正确的资料,比如引用[1]、[2]、[3]来支持各个要点,让回答更具权威性。</think>### C语言extern关键字详解 #### 一、extern的核心作用 1. **声明外部符号** extern用于告知编译器:当前符号(变量/函数)的定义存在于其他源文件中,无需在当前文件重复定义。例如在文件A中声明`extern int global_var;`,实际定义可能存在于文件B中[^3]。 2. **避免重复定义** 在多个文件共享全局变量时,使用extern可防止因重复定义导致的链接错误。例如: ```c // file1.c int shared_value = 100; // 实际定义 // file2.c extern int shared_value; // 仅声明 ``` 3. **增强代码扩展性** 将符号定义与使用分离,便于模块化开发。修改全局变量时只需调整定义文件,无需改动所有引用文件[^3]。 #### 二、典型使用场景 1. **跨文件共享全局变量** ```c // data.c int sensor_data[100]; // 定义全局数组 // process.c extern int sensor_data[]; // 声明外部数组 void process_data() { printf("%d", sensor_data[0]); } ``` 2. **跨文件调用函数** 函数默认具有外部链接属性,但显式声明更清晰: ```c // math.c int add(int a, int b) { return a + b; } // main.c extern int add(int, int); // 显式声明(可省略) int main() { printf("%d", add(2,3)); // 输出5 [^2] } ``` 3. **头文件集中管理声明** 最佳实践:在头文件中声明extern变量,源文件包含使用: ```c // config.h extern const float PI; // config.c const float PI = 3.14159; // main.c #include "config.h" ``` #### 三、注意事项 1. **变量声明vs定义** - 声明:`extern int var;`(不分配内存) - 定义:`int var = 10;`(分配内存) 2. **与static的对比** | 特性 | extern | static | |------------|-------------------|------------------| | 作用域 | 跨文件可见 | 仅当前文件可见 | | 存储期 | 静态存储期 | 静态存储期 | | 初始化 | 定义时初始化 | 必须初始化 | 3. **常见错误示例** ```c // 错误:extern与初始化同时使用 extern int error_var = 10; // 实际变成定义 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fengwang0301

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值