【C语言】static 和 extern 的理解和应用。

对于 C 语言的初学者,对 static 和 extern 的理解可能会遇到一些问题。

用在哪?

首先明确 static 和 extern 可以用在哪?
static 和 extern 都可以用来修饰【变量】和【函数】。ok,知道这么多就行了,所谓实践出真知,下面直接举例

举例

  1. extern 修饰全局变量
// file1.c
int a = 0;// file2.c
extern int a;
printf("a=%d", a);

即在 file2.c 中可以通过 extern 来使用定义在 file1.c 中的 a 变量。(必须要通过CMakeLists.txt将其都包含在源文件中)
如果使用 static 修饰 a 的话,这 a 这个变量只能在 file1.c 这个文件中使用,不能通过 extern 在其他文件中使用。比如这么写就是错的:

// file1.c
static int a = 0;// file2.c
extern int a; //此处会报错
printf("a=%d", a);

思考一个问题,如果 file2.c 直接 #include “file1.c”,那么可以用 a 变量吗?(答案是可以,因为#include 相当于把 file1.c 直接写到 file2.c 中,它两相当于是同一个文件,注意别在CMakeLists.txt中包含 file1.c 了,会报参数定义重复的问题)

  1. extern 修饰局部变量
// file1.c
int a = 0;// file2.c
void printA() {extern int a;printf("a=%d", a);
}

即此时 通过 extern 将 a 在 printA() 方法中引入,只在 printA() 方法中可见。

  1. static 修饰局部变量
void increaseA(){static int e = 0;e++;printf("e=%d\n", e);
}int main() {increaseA();increaseA();increaseA();increaseA();increaseA();increaseA();return 0;
}

输出:

e=1
e=2
e=3
e=4
e=5
e=6

说明什么呢?说明 e 是一直存在的,直到程序结束才释放,只是其使用的作用域在 increaseA() 方法内。

  1. extern 修饰方法
//file1.c
void test1(){//...
}//file2.c
extern void test1(); int main(){test1();
}
  1. static 修饰方法
//file1.c
static void test1(){//...
}//file2.c
extern void test1(); //这里是错的,无法编译
  1. static 修饰的头文件变量
//file1.h
static a = 1;//file2.c
#include "file1.h"printf("a=%d",a); //输出 1
a = 2;
printf("a=%d",a); //输出 2//file3.c
#include "file1.h"
printf("a=%d",a); //输出 1
a = 3;
printf("a=%d",a); //输出 3

可以看到,在 file2.c 中 修改了 a 并不影响 file3.c 中的值。为啥?因为 #include 相当于将 file1.h 直接写到了 file2.c 和 file3.c 中,而 a 只在文件内有效,所以其实相当于是在 file2.c 和 file3.c 中各定义了一个 a, 是两个不同的变量,互不影响。

总结

  1. static关键字用于局部变量时,会将变量的生命周期从自动存储期扩展到整个程序的执行期间。
  2. static用于全局变量或函数时,改变的是它们的链接属性(从外部链接到内部链接),生命周期仍然是整个程序的执行期间。
  3. extern关键字不创建变量或函数,因此不影响生命周期,它用于声明在其他地方定义的全局变量或函数以便跨文件访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/197755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity动画】为一个动画片段添加事件Events

动画不管播放到那一帧,我们都可以在这里“埋伏”一个事件(调用一个函数并且给函数传递一个参数,参数在外部设置,甚至传递一个物体)! 嗨,亲爱的Unity小伙伴们!你是否曾想过为你的动画…

常用性能工具与性能分析

iperf3 iperf3是一个用于测量网络带宽和性能的工具。它支持客户端-服务器模式,通过在客户端和服务器之间进行数据传输来评估网络的吞吐量、延迟和丢包率等指标。 iperf3的基本使用方法: 1. 安装iperf3: 首先,你需要在客户端和…

WPF halcon 机器视觉

1 鼹鼠的故事第14集 鼹鼠与智能房 鼹鼠无意中坐进了一辆小汽车,小汽车开进了一所智能住宅。鼹鼠看到房主在智能房里,享受着现代化的服务。趁着主人看电视的时候,鼹鼠也享用了一顿丰盛的智能晚餐。 小编大胆的畅想,这些食物 前一秒…

创建conan包-打包现有二进制文件

创建conan包-打包现有二进制文件 1 Packaging Existing Binaries1.1 Packaging Pre-built Binaries1.2 Downloading and Packaging Pre-built Binaries 本文是基于对conan官方文档Packaging Existing Binaries翻译而来, 更详细的信息可以去查阅conan官方文档。 1 P…

Ubuntu开机出现Welcome to emergency mode解决办法

问题描述 笔记本电脑安装了windows 10和ubuntu 16.04双系统,windows系统关机时按电源键强制关机,再次开机进入Ubuntu系统时无法进入图形界面,出现Welcome to emergency mode。 问题分析 异常关机导致文件系统受损,依据提示使用…

上传文件获得下载链接方法:直链!直链!

!非 百度网盘 不是直接用网盘下载,要用直链,百度上有很多方法。 我自己研究了个,跳过百度网盘输密码进网页的方法 还是先还是要把文件上传网盘让后搜索网盘获取直链的方法(那百度网盘举例) 地址 https:…

数据结构:字典树(前缀树,Trie树),压缩字典树(Radix)

字典树Trie Tree 字典树也称前缀树,Trie树。在 Elasticsearch 的倒排索引中用的也是 Trie 树。是一种针对字符串进行维护的数据结构。 字典树是对词典的一种存储方式,这个词典中的每个“单词”就是从根节点出发一直到某一个目标节点的路径,…

<JavaEE> 多线程编程中的“等待和通知机制”:wait 和 notify 方法

目录 一、等待和通知机制的概念 二、wait() 方法 2.1 wait() 方法的使用 2.2 超时等待 2.3 异常唤醒 2.4 唤醒等待的方法 三、notify() 方法 四、notifyAll() 方法 五、wait 和 sleep 的对比 一、等待和通知机制的概念 1)什么是等待和通知机制&#xff1f…

EM32DX-E4【C#】

1外观: ecat总线,分布式io 2电源: 靠近SW拨码:24V 中间:0V 靠近面板:PE接地 3DI: 6000H DI输入寄存器 16-bit (16位输入) 00H U8 子索引总数 01H Unsigned16 IN1…

事务管理 springboot

事务是一组操作的集合 它是一个不可分割的工作单位 这些操作 要么同时成功要么同时失败 Spring事务管理 #Spring事务管理日志 logging: level: org.springframework.jdbc.support.JdbcTransactionManager: debug

【深度学习】回归模型相关重要知识点总结

回归分析为许多机器学习算法提供了坚实的基础。在这篇文章中,我们将总结 10 个重要的回归问题和5个重要的回归问题的评价指标。 一、线性回归的假设是什么 线性回归有四个假设: 线性:自变量(x)和因变量(y&…

JWT 认证机制

1. Session 认证的局限性 Session 认证机制需要配合 Cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端按口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。 注意: 1&#xf…

CoreDNS实战(一)-构建高性能、插件化的DNS服务器

1 概述 在企业高可用DNS架构部署方案中我们使用的是传统老牌DNS软件Bind, 但是现在不少企业内部流行容器化部署,所以也可以将Bind替换为 CoreDNS ,由于 CoreDNS 是 Kubernetes 的一个重要组件,稳定性不必担心,于此同时还可将K8S集…

linux系统中安装nginx到指定目录

linux系统中安装nginx到指定目录 下载要求版本的nginx源码包 上传并解压nginx源码包 # 在/opt/app目录下创建nginx解压安装目录 cd /opt/app mkdir nginx# 切换到解压目录下 cd /opt/app/nginx# 解压 tar -zxvf nginx-1.24.0.tar.gz编译安装 # 在/opt/app/nginx路径下&…

智能优化算法应用:基于社会群体算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于社会群体算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于社会群体算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.社会群体算法4.实验参数设定5.算法结果6.参考…

【unity3D】unity中如何查找和获取游戏物体

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity中游戏物体的查找与获取 这里写自定义目录标题 获取当前物体的基本属性查找其它物体- 通过名称查找其它物体- 通过标签查找- 通过类…

PostgreSQL 连接更新操作

假设有两个表,table_a 和 table_b,它们有一个共同的列 common_column,我们想要通过连接这两个表并根据某些条件更新 table_a 的列。 -- 创建表 table_a CREATE TABLE table_a (id SERIAL PRIMARY KEY,common_column INT,data_a VARCHAR(255)…

使用UART和USART在STM32上进行双向通信

在本文中,我们将深入了解如何在STM32上使用UART(通用异步收发传输器)和USART(通用同步异步收发传输器)实现双向通信。UART和USART是常见的串口通信协议,通常用于与其他设备进行数据传输。我们将重点介绍如何…

基于PaddleSeg开发的人像抠图web api接口

前言 基于PaddleSeg开发的人像抠图web api接口,提取官方代码,适配各种系统,通过api的接口进行访问。 环境要求 1、Python3.7以上 2、源码(文章最后下载) 源码结构 测试module.py中添加如下代码: if __na…

java中IntStream.range()的用法实例?

IntStream.range()是Java中java.util.stream.IntStream类提供的一个静态方法,用于生成一个顺序的整数范围。它可以用于创建一个包含指定起始值(包含)和结束值(不包含)之间所有整数的流。 下面是一个使用IntStream.ran…