C语言知识(1) static修饰详解分享

news2024/12/26 11:05:48

1.前言

哈喽大家好啊,今天来给大家分享c中static的使用,希望能对大家有所帮助,请大家多多点赞,收藏支持我哦~

2.正文

在讲解static之前,先给大家铺垫三个概念,方便大家理解。

2.1三则知识铺垫

2.1.1作用域与生命周期

2.1.1.1作用域

作用域(scope)主要用来控制变量、函数或对象在程序中的可见性和生命周期。具体来说,作用域限定了一个变量、函数或对象在代码中的哪一部分可以被访问和使用。作用域的种类包括全局作用域、局部作用域和块级作用域。

2..1.1.2生命周期

生命周期,也指生存期(Lifetime),通常指的是一个对象、变量或数据结构在内存中存在的时间长度,即从它被创建或分配内存开始,到它不再被需要并被销毁或释放内存为止的这段时间。

3..1.1.3作用域和生命周期的联系

变量的作用域决定了它在代码中的可见性,而生存期决定了它在内存中的存在时间。虽然作用域和生存期经常是相关的,但它们不是同一个概念。例如,在C++中,一个局部变量在其作用域内是可见的,并且当控制流离开其定义的作用域时,它的生存期就结束了。总而言之,一个关注存活时间,另一个关注可适用范围。

2.1.2内存

相信读者会有一个疑问,我们static为什么要讲内存呢,因为static的使用本质上牵扯到一些内存的概念,将这里理解了就会对static的使用带来极大的帮助。

 

  • 栈区是一种后进先出的数据结构,用于存储程序运行时的局部变量和函数调用信息。当一个函数被调用时,其局部变量和函数参数会被分配到栈上。当函数返回时,这些变量会自动被销毁,栈的空间会被回收。。
  • 堆区是用于动态分配内存的区域,通常用于存储程序中需要在运行时进行分配和释放的数据。
  • 静态区(也称为全局区)用于存储程序中声明为静态的全局变量和静态局部变量。这些变量在程序运行期间都存在,并且它们的值在函数调用之间保持不变。静态区是在编译时分配内存空间的,因此其大小和位置在程序运行期间是固定的。静态区的生命周期与整个程序的执行周期相同,直到程序结束才由系统释放内存。

3.1.3链接属性

链接属性分别包括外部链接属性和内部链接属性。详细解释如下:

  • 外部链接通常指的是程序中定义的标识符(如全局变量或函数)在多个编译单元(通常是源文件)之间的可见性和共享性。当一个标识符被声明为具有外部链接时,它可以在整个程序的不同部分中被访问和引用,就好像它们是同一个实体一样。
  • 内部链接(也称为静态链接)是指标识符的作用域限制在其定义的编译单元内。与外部链接不同,具有内部链接的标识符在链接过程中不会暴露给其他编译单元,也不会与其他编译单元中的同名标识符发生冲突。

2.2static的使用

上面铺垫了这么多,接下来开始上正餐:

2.2.1修饰局部变量

接下来我举例子会使用包含俩个函数的代码:

第一段代码:

#include <stdio.h>  
void func() {
    int i = 0;
    i++;
    printf("%d\n", i);
}
int main() {
    for (int i = 0; i < 5; i++) {
        func();
    }
    return 0;
}

输出结果如图:

我们发现,上段没有实现逐个打印1,2,3,4,5的功能,那是因为func函数中i一旦完成便被销毁下一次for循环再进行func函数时,便还是重新创建i=0的操作。

第二段代码:

#include <stdio.h>  
void func() {
    static int i = 0;
    i++;
    printf("%d\n", i);
}
int main() {
    for (int i = 0; i < 5; i++) {
        func();
    }
    return 0;
}

输出结果如图:

经过static的修饰后,我们发现可以输出1,2,3,4,5了。因此我们可以得出,static的修饰本质上是使变量的生命周期得到了改变,i这个局部变量本来是储存在栈区,经修饰后储存在了静态区,特征就相当于全局变量了,生命周期延长,但作用域不变。

2.2.2修饰全局变量

局部变量经过static的修饰以后使用可以相当于全局变量,那么static修饰全局变量会有什么影响呢。

为了能够表现出static修饰全局变量后的效果,这里要引用一个extern

extern 是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使用extern。

代码1:(以下是俩个源文件)
int a = 1;
#include<stdio.h>
int main() {
	extern int a;
	printf("%d", a);
	return 0;
}

这个代码可以正常输出1;

代码2:

static int a = 0;
#include<stdio.h>
int main() {
	extern int a;
	printf("%d", a);
	return 0;
}

用编译器一编译发现,这段代码没有办法正常输出。由此我们可以得出被static修饰后的全局变量只能在当下源文件去使用,全局变量本身是被默认具有外部连接属性,被修饰后该变量由外部连接属性变成内部连接属性,即使声明了,也是无法正常使用。

使⽤建议:如果⼀个全局变量,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤ static修饰。

 2.2.3修饰函数

接下来再给大家附上俩段代码

代码1:

int func(int x, int y) {
	return x + y;
}
#include<stdio.h>
extern int func(int x ,int y);
int main() {
	int a = 0, b = 0;
	scanf("%d%d", &a, &b);
	printf("%d",func(a, b));
	return 0;
}

 这段代码运行后发现可以实现调用加法函数的功能,即能正常输出a+b的值。

代码2:

extern int func(int x, int y) {
	return x + y;
}
#include<stdio.h>
extern int func(int x ,int y);
int main() {
	int a = 0, b = 0;
	scanf("%d%d", &a, &b);
	printf("%d",func(a, b));
	return 0;
}

 调试后发现,这段代码无法正常输出,原因和static修饰全局变量类似,函数本身带有外部链接属性,经过extern修饰后,转换成内部链接属性,则函数的调用仅限于当前源文件中了。

使⽤建议:如果⼀个函数,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤ static修饰。

3.小结

今天的分享到这里就结束了,希望喜欢的朋友多多支持我哦~

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

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

相关文章

Windows突然蓝屏解决办法

Windows突然蓝屏&#xff0c;然后重复开机没有用&#xff0c;但是能进入bios系统&#xff0c;证明内存和磁盘没事&#xff0c;用大白菜制作了PE系统盘制作过程&#xff08;之前一直都是用官方镜像制作&#xff0c;但是发现用大白菜制作可以对系统之前的磁盘里面重要的信息拷贝到…

Pixverse:开启文生视频与图生视频新纪元

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

“广进计划”中的特斯拉,加码驱动Robotaxi能否迎来新未来?

近期&#xff0c;特斯拉可以说是热搜上的常驻选手。 公司先是透露将于8月8日推出自动驾驶出租车Robotaxi&#xff0c;再是宣布将开启“广进计划”&#xff0c;在全球范围内裁员10%。官方资料显示&#xff0c;截至2023年末&#xff0c;特斯拉全球拥有超14万名员工&#xff0c;此…

OpenVINO安装教程 Anaconda版

从 Conda Forge 安装 OpenVINO™ Runtime 请注意&#xff0c;Conda Forge 发行版&#xff1a; 提供 C/C 和 Python API 不支持 NPU 推理 专用于所有主要操作系统的用户&#xff1a;Windows、Linux 和 macOS &#xff08;所有 x86_64 / ARM64 架构&#xff09; 使用 Anaconda…

CSS导读 (CSS的三大特性 上)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 五、CSS的三大特性 5.1 层叠性 5.2 继承性 5.2.1 行高的继承 5.3 优先级 小练习 五、CSS的三大特性 …

Windows电脑上能用的便签记事软件

上班族大多都依赖电脑进行办公&#xff0c;他们在电脑上完成各式各样的工作任务。因此&#xff0c;下载并安装高效率的软件成了提升工作效率的关键。其中&#xff0c;一款好的便签软件能够极大地帮助他们管理和跟踪任务。那么&#xff0c;有没有一款适合在电脑上使用的出色的便…

【c语言】自定义类型:结构体详解

目录 自定义类型&#xff1a;结构体 结构体类型的声明 结构体变量的创建和初始化 结构的特殊声明 结构的自引用 结构体内存对齐 对其规则 为什么存在内存对齐&#xff1f; 修改默认对⻬数 结构体传参 结构体实现位段 位段的内存分配 位段的跨平台问题 位段的应用…

github克隆报错:failed: The TLS connection was non-properly terminated.

github克隆gazebo_ros_control报错 fatal: unable to access https://github.com/ros-controls/gazebo_ros_control.git/: gnutls_handshake() failed: The TLS connection was non-properly terminated. sudo apt-get install ros-noetic-gazebo-ros-control git 克隆gazeb…

超越GPT-4V,苹果多模态大模型上新,神经形态计算加速MLLM(二)

上文介绍基于MINOnets神经网络架构加速多模态大模型的策略&#xff0c;本文将以Spinnaker2多核神经网络芯片EGRU架构为起点&#xff0c;覆盖存内计算架构&#xff0c;介绍新型计算架构在加速大模型推理的作用。SpiNNaker 2是一个设计用于大规模异步处理的多核神经形态芯片&…

如何封装Vue组件并上传到npm

前言 环境准备 1.注册npm账号&#xff1a;npm | Home (npmjs.com) 2.保证当前环境安装了vue、webpack、node&#xff0c;以下工作将在该环境下进行&#xff08;没有的小伙伴自行百度安装哈~&#xff09; 3.一下用到的环境版本 webpack&#xff1a;v5.1.4node&#xff1a;v…

每日一题---OJ题: 旋转数组

片头 嗨! 小伙伴们,咱们又见面啦,今天我们一起来学习一道OJ题---旋转数组 emmm,看上去好像没有那么难,我们一起来分析分析 比如: 数组里面有7个元素,分别为 1, 2, 3, 4, 5, 6, 7 , 现在我们将数组中的元素向右轮转3个位置 第一次轮转:将最后一个元素"7"放在第一个…

【spring】@Resource注解学习

Resource介绍 在Spring框架中&#xff0c;Resource 注解是一个JSR-250标准注解&#xff0c;用于自动装配&#xff08;autowiring&#xff09;Spring容器中的bean。Resource 注解可以用于字段、方法和方法参数上&#xff0c;以声明依赖注入。 Resource源码 Target({TYPE, FIE…

通付盾APP尽职调查报告:守护移动应用安全新篇章

在数字化浪潮席卷全球的今天&#xff0c;移动应用程序已经成为我们生活中不可或缺的一部分。无论是购物、社交、娱乐还是工作&#xff0c;我们几乎每天都在与各种各样的APP打交道。然而&#xff0c;随着APP的广泛应用&#xff0c;其安全问题也日益凸显&#xff0c;成为开发者和…

初学python记录:力扣928. 尽量减少恶意软件的传播 II

题目&#xff1a; 给定一个由 n 个节点组成的网络&#xff0c;用 n x n 个邻接矩阵 graph 表示。在节点网络中&#xff0c;只有当 graph[i][j] 1 时&#xff0c;节点 i 能够直接连接到另一个节点 j。 一些节点 initial 最初被恶意软件感染。只要两个节点直接连接&#xff0c…

Python LEGB规则

Python在查找“名称”时&#xff0c;是按照LEGB规则查找的&#xff1a; Local&#xff1a; 指的就是函数或者类的方法内部 Enclosed&#xff1a; 指的是嵌套函数&#xff08;一个函数包裹另一个函数&#xff0c;闭包&#xff09; Global&#xff1a; 指的是模块中的全局变量 Bu…

【服务器部署篇】Linux下Nginx的安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

MySQL事务的性情很“原子“,要么执行要么不执行

各位小伙伴有没遇到这个奇葩情况&#xff1a;业务逻辑对两个表加了事务操作&#xff0c;A表的存储引擎是InnoDB&#xff0c;B表的存储引擎却是MyISAM。事务要回滚时&#xff0c;麻烦就来了hhh&#xff0c;B表它回滚不了&#xff0c;那小伙伴打算要怎么处理~ &#x1f331;以【…

C#创建随机更换背景图片的窗体的方法:创建特殊窗体

目录 一、涉及到的知识点 1.图片资源管理器设计Resources.Designer.cs 2.把图片集按Random.Next方法随机化 3.BackgroundImage属性 二、实例设计 1. Resources.Designer.cs 2.Form1.Designer.cs 3.Form1.cs 4.生成效果 很多时候&#xff0c;我们需要每次打开窗体时能够…

如何创建二级域名并解析到服务器

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的全栈工程师 欢迎分享 / 收藏 / 赞 / 在看…

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data = readNPY(train.npy);%% 提取标签的坐标 first_label = squeeze(npy_data(2,1,:,:)); h = fspecial("gaussian&q…