前面总结了static关键字,下面先说说static和extern能同时使用吗? 答案是不能。

 

extern修饰全局变量和函数,被修饰的变量和函数可以在别的文件里使用。
static修饰的变量和函数作用范围仅限于定义它的文件内部。 

static要求去除符号表名称,extern要求通过符号名称链接,他俩先天就矛盾,不能一起使用。

 

说起extern 这个关键字,相信大家都用的很多,一般都是在编译程序的时候,出现了全局变量找不到,不是定义在本文件中,然后就会在前面加上extern来解决这类编译错误。 相对其他关键字,extern的使用比较简单。在此做个简单总结:

 

1.了解extern

        1.extern是C语言的一个关键字,可以用来修饰函数与变量

        2.当extern修饰一个变量或函数时时,就是在声明这个变量(函数),告诉编译器在外部文件中已经这个变量(函数),要通过编译。

  3.extern关键字是C语言中的一个存储类别修饰符,它用来声明一个变量或函数是在其他文件中定义的,

 2.extern的用法

在C语言中变量和函数有数据类型和存储类型两个属性,因此变量定义的一般形式为:存储类型 数据类型 变量名表;

C语言提供了一下几种不同的存储类型:

(1)  自动变量(auto)--------局部变量默认一般就是这个类型,

(2)  静态变量(static)-------前面学习过

(3)  外部变量(extern)-------这次学习的

(4)  寄存器变量(register)-------很少显示看见

(上面的auto、static、extern、register都是C语言的关键字),这里只分析extern关键字的使用

外部变量(全局变量)extern----全局静态存储区

标准定义格式:extern 类型名 变量名;

        1.在一个文件中引用其他文件的变量

        当我们一个项目中有多个.cpp文件时,往往需要在其中一个文件中使用另一个文件中定义的变量,如果我们直接使用,编译器就会报错:

 由于编译文件1的时候编译器不认识g_val,以此编译失败

这时我们就可以使用extern,如下:

//文件1.cpp代码
 
#include<stdio.h>
extern int g_val;    //声明外部符号g_val
int main()
{
    printf("%d", g_val);
}
 
 
//文件2.cpp代码
int g_val = 10;

这时,代码就可以成功运行起来,打印出g_val的值。

 

2.在一个文件中引用其他文件的函数

        对于函数,也是同理,当需要使用外部文件定义的函数时,需要使用extern关键字进行声明:

//文件1.cpp代码
#include<stdio.h>
extern void show();    //声明外部符号show()
int main()
{
    show();
}
 
//文件2.cpp代码
#include<stdio.h>
void show()
{
    printf("hello world");
}

运行结果如下:

hello world        

3.extern的注意事项

        在使用extern时我们可能会写出这样的代码 :

//文件1.cpp代码
 
#include<stdio.h>
extern int g_val=10;
int main()
{
    printf("%d", g_val);
}
 
 
//文件2.cpp代码
int g_val = 10;

上述代码是在引用外部变量g_val的时候同时对它进行赋值,当我们运行时,编译器就会报错,这个错误是在链接的时候发生的错误,为“找到一个或多个多重定义的符号” 。

  产生错误的原因时什么呢 ?这就不得聊到定义与声明了。

  1.什么定义:
        定义是给变量或函数分配内存空间,在这同时可以为变量赋初值。
       

  2.什么是声明:
        声明是用来告诉编译器变量的名称和类型,使编译器知道存在着这个变量和类型,且不分配内存。
    

  3.结论
        由此我们可以得出以下两种结论:

        1.定义会对变量分配内存空间,而声明不会

        2.由于一个变量的存储空间是唯一的,因此定义不能重复定义,而声明可以重复声明。

 


 

由此可以得出,当我们使用extern修饰变量且对它进行赋值的时候,这条语句就不是在对变量进行声明了,而是定义,因为声明一个变量编译器是不会分配内存空间的,而对于一个不存在的内存空间进行赋值操作,显然是不合理的。
而当我们进行定义的时候,编译器在编译的时候并不会发现错误,但在多文件进行链接时,就会发现g_val这个全局变量同时在1.cpp和2.cpp进行定义,报出了重定义的错误。

 extern关键字的作用有以下几点:

  •  
    - 可以避免变量或函数的重复定义,提高代码的可维护性和可读性。
  •  
    - 可以实现跨文件的数据或功能的访问,提高代码的复用性和灵活性。
  •  
    - 可以控制变量或函数的作用域和链接属性,提高代码的安全性和效率。
  •  
     

    extern关键字的注意事项

     

     

     

    extern关键字是C语言中的一个存储类别修饰符,它用来声明一个变量或函数是在其他文件中定义的,也就是说,它是一个外部的变量或函数。
    extern关键字可以让不同的文件之间共享变量或函数,实现模块化编程。extern关键字的作用有避免重复定义,实现跨文件访问,控制作用域和链接属性等。
    extern关键字的用法有声明全局变量,声明函数,声明常量,声明数组等。extern关键字的注意事项有不能用于定义,不能用于声明局部变量,不能用于声明静态变量,声明和定义要一致,声明可以多次,定义只能一次等。

     

 

4.extern与include
        1. include
        当我们有多个文件需要大量引用外部变量或函数的时候,如果使用extern,我们就需要在多个文件中大量使用extern,这样做效率显然会降低,代码也显得太过LOW。因此,我们通常将所有的全局变量和常用全局函数都写在一个.cpp文件中,然后用同名的.h文件放这些变量与函数的声明(即头文件),这样其他文件需要使用外部变量和函数时,就只需要包含其中的头文件即可,显得高效又简洁。如:
//文件1cpp代码
#include "2.h"
int main()
{
    show();
    printf("%d", g_val);
}
 
//文件2.cpp代码,用于定义与实现
#include "2.h"
int g_val = 10;
void show()
{
    printf("hello world");
}
 
//文件2.h代码,用于声明
#pragma once           //防止重复包含   //还有一种可以防止重复包含的方法:#define  XXX
#include<stdio.h>
extern int g_val;
void show();

这样,当我们需要使用2.cpp中的变量和函数时,就不需要再使用extern声明了,包含2.h就可以了。

  2.extern的好处

        想必会有读者有疑问,include那么方便,那我们的extern关键字是不是没有用了?实则不然。原因如下:

        1.当头文件中有大量的变量与函数时,如果我们只需要其中的少量变量或函数时,我们使用include包含,显然会引入大量不需要的无关函数与无关变量,这样无疑会减慢程序预处理的过程,此时使用extern就可以有效缩短时间。

        2.在大工程中,一个头文件中经常会包含其他的头文件,这样层层嵌套下来,如果没有进行处理,往往会出现一个.c文件重复包含相同头文件的情况,而使用extern就不会出现这种情况。(当然,如果头文件进行适当的处理如“条件编译”,也能有效地避免重复包含的现象,这里先暂时不做详细讨论)

 


帖子:                       
原文链接:https://blog.csdn.net/m0_69909682/article/details/128218337

https://blog.csdn.net/u012730525/article/details/136230556

https://blog.csdn.net/apple_51801179/article/details/125758014

posted on 2024-04-02 13:56  shiyuan310  阅读(106)  评论(0编辑  收藏  举报