首页 > 其他分享 >extern 关键字------非原创

extern 关键字------非原创

时间:2024-04-02 14:00:12浏览次数:22  
标签:文件 函数 关键字 定义 ------ extern 变量

前面总结了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

标签:文件,函数,关键字,定义,------,extern,变量
From: https://www.cnblogs.com/beilou310/p/18110434

相关文章

  • [附源码]JAVA计算机毕业设计电影售票app(源码+开题)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展,人们的生活方式发生了翻天覆地的变化。特别是在娱乐消费领域,电影作为一种大众喜爱的文化产品,其市场规模逐年扩大。然而,传统的......
  • C语言基础-标准输入输出
    标准库实现了简单文本的输入输出模式。以下的示例在使用时都需要先包含标准输入输出头文件stdio.h#include<stdio.h>输入getchar函数intgetchar(void);从标准输入(一般为键盘)中一次获取一个字符调用时,返回输入的字符遇到文件结尾时返回EOFEOF也定义在stdio.h中,其......
  • MySQL-linux安装-万能RPM法
    一、MySQL的Linux版安装1、CentOS7下检查MySQL依赖1.检查/tmp临时目录权限(必不可少)由于mysql安装过程中,会通过mysql用户在/tmp目录下新建tmp_db文件,所以请给/tmp较大的权限。执行:chmod-R777/tmp2.安装前,检查依赖rpm-qa|greplibaiorpm-qa|grepnet-tools......
  • 大数据环境下 实现每天千万级地址关联 10万/秒
    地名作为最常用的社会公共信息,不仅与人们的日常生活息息相关,而且是政府行政行为、经济建设不可缺少的基础信息资源。在政务系统中有许多需要将业务地址关联到标准地址的场景,addresstool致力于解决地址关联匹配算法中的速度和准确性问题。经实测,单核addresstool的地址关联速......
  • 【EI会议】2024年机械制造、智能控制与计算机科学国际会议(MBICCS 2024)
    2024InternationalConferenceonMachineBuilding,IntelligentControlandComputerScience(MBICCS2024)会议地点:西安,中国截稿时间:2024.4.16网址:www.mbiccs.com邮箱:[email protected]投稿主题请注明:MBICCS2024+通讯作者姓名●会议简介2024年机械制造、智......
  • APP自动化测试-Appium元素定位之元素等待
    一、什么是元素等待元素等待的意义在Appium自动化测试中,元素等待是一个重要的环节。当脚本执行速度较快,而页面元素尚未加载完成时,就会导致脚本无法定位到元素,从而使执行失败。因此需要设置元素等待,从而增强脚本的健壮性,提高执行效率。元素等待的主要目的是确保在执行操作......
  • 第二期书生浦语大模型实战营第一次作业(大模型技术报告解读)
    书生·浦语大模型全链路开源体系上海人工智能实验室与商汤科技联合香港中文大学、复旦大学发布新一代大语言模型书生·浦语2.0(InternLM2)。这个大模型包含70亿和200亿两种参数规格,以及基座、对话等版本,向全社会开源并提供免费商用授权。书生·浦语2.0(英文名:InternLM2)核心理念:......
  • golang中GORM使用 many2many 多对多关联查询-详细案例
    表结构和数据user表CREATETABLE`user`(`id`bigint(20)NOTNULL,`user_key`bigint(20)NOTNULL,`account`char(32)NOTNULL)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;为了测试将user_key和id写入同样的值数据:+----+----------+---------+|id|user_k......
  • 小美的外卖订单(美团2024届秋招笔试第一场编程真题)
    题面核心思想折扣价不能大于原价原价才能参与满家原价、折扣价和满减的价格都必须是正实数格式化输出代码importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){finallongMOD=(long)(1e9+7);Scanner......
  • [转帖]nginx重试机制proxy_next_upstream
    https://www.cnblogs.com/cyleon/p/11023229.html nginx作为反向代理服务器,后端RS有多台服务器,上层通过一定机制保证容错和负载均衡。nginx的重试机制就是容错的一种官方链接:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstreamproxy_next_......