c语言staticint的作用,C语言 static 声明静态变量?大佬原来用它干这事!

article/2025/9/30 10:17:20

原标题:C语言 static 声明静态变量?大佬原来用它干这事!

C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它!

高手在写代码的时候,会特别注重的一点就是,对外的方法对外,不对外的方法和数据,都是让其对外不可见,也就是俗称的,内部不想让别人直接访问的方法,变量,就不要让其可以访问到,从而保证几点:

1 不污染全局符号

2 数据和方法保证不被不规范的引用

而C语言中的关键字 static 就是起这个作用,我们这节来讲讲这个玩意。再说这个前,我想跟大家先讲一个内容,之前也说过。

代码段

数据段

BSS段

代码段是只读区域,这个段落不允许修改,加载时候会指定只读。

数据段分为,只读区域和可变区域。只读区域就是类似于常量数据,还有常量字符串这些,同时还有一些使用const 关键字修饰的,会放到这里,标记只读,保证数据不会被随意修改。

BSS段放置的是全局的未初始化的变量,这个编译成可执行文件因为没有初始化数据,所以可执行文件中就不占大小,但是如果初始化了,就会占大小。

堆,我们使用 malloc 申请内存空间,就是在这个区域,这个区域是需要主动去释放空间,否则会内存泄漏。

栈,函数内部的局部变量,以及函数之间调用,临时使用的空间,这个是依赖栈的压入,弹出机制,重复在用。(这里用一个网上图片,大家一目了然)

639793696b91c25987eb6277ba8c91c9.png

栈我们一般不用关注,它会自动平衡,但是我们一般在栈里面要考虑的就是栈溢出。栈也是有大小的,系统会分配一段区域,用在压栈,弹出操作,如果你两个函数相互调用,就会出现栈溢出。

为什么要说这个?其实就是因为 static 关键字,有一个功能,就是会让局部变量本该在栈上,用这个声明后,就会进入全局区域,也就是从栈区域,进入到数据区域。

下面我们来看下代码:add.c

edabf7b4803dbbc1b31544bb0b55652d.png

hello.c

1eb7715f0e33d7046a8616602c8b9f25.png

我们这里看下,没有#include “add.h”, 我们使用

gcc -o add.o -c add.c

gcc -o hello.o -c hello.c

gcc -o hello hello.o add.o

发现是可以编译过,也能链接过,也能运行。我们使用readelf-sadd.o ,看到信息,add前面有个Bind的值是GLOBAL,这个就是说明,add是在可以让其他.o链接时候去查找的一个符号,它的类型是func函数。

434f1b86ae018be33638af6c310ac18d.png

然后我们把add.c 改成这个:(前面加上一个static)

646f204fd34032bdbe7c191a231e484d.png

编译链接就会失败,找不到add方法,那么我们readelf -s add.o再看下:

65d0a21bafde48438e89707022fd12f5.png

add前面Bind的值变成了LOCAL,这时候对外就不可见了。这也就是static在全局的时候,起的作用,将对应的变量,或者函数的可见范围,变成只对自身可见,对外不可见。

这个是为了降低重名的几率,也是防止自身的全局变量被外部访问,瞎修改的风险。

为了说明这个情况,我们来演示下这个过程,add.c改成这样:

572f20b60b2ae28c822d502acfaef964.png

hello.c 改成

982c9eb5fbb121bd46f0537d7c261901.png

编译执行后,最终结果输出17,是不是让我们一下子就不明白,a b两个值被外部随意修改,导致没法看懂代码业务。

f4f27480d4562e21197117d7c2681aec.png

我们看到有两个类型是 OBJECT 的数据,全局的,a和b。这样子这两个值就是可以被外部引用,进行修改的了。

如果我们把 add.c 中的 int a=5;改成static int a=5;那么最终链接的时候hello.o 就找不到a变量,导致链接失败。

这也就是static的作用,让只想对当前的.c能访问,做的对修饰的变量或者函数进行限定。

于是,我们常规的模式就是,对内的都用static进行修饰,然后放出对外函数,让其操作数据,保证入口的统一性,也更容易追踪。具体如下:

f8f6e32a25e9f90202ce85f9d5df033d.png

用静态修饰变量,不让外部直接访问,然后对外放出函数,让其通过函数修改数据,保证了入口的唯一性,这样子调试也很简单,直接在函数设置断点,打印堆栈,直接能找到调用方。

而如果说你让int a这种随意的变量放置到全局,就是一个灾难,会出现莫名奇妙被修改,找半天找不到被谁修改的问题。

说完了全局变量,全局函数前面加static,下来说下函数内部,添加static的妙用。

函数中的局部变量,默认是都在栈上面,这类变量最大的特点就是,函数返回之后,这段区域就会被其他函数调用时覆盖,重复利用,这也是栈的特点。

那么如果我们想做一个记数,用来记录这个 add 函数被调用的次数。该如何设计呢?

我们可以用一个全局静态变量来记录,比如 static int call_add_times=0;

然后在add方法里面进行记数,这样来操作。

这样子不舒服的一点就是,本该是在add内部的一个变量,被丢到全局区域,这样子就会有个问题,会被本文件的其他地方调用,但我们设计的这个变量,只想让add函数用。

于是,我们可以这样子处理:

int add

{

static int call_add_times=0;

call_add_times++;

return a+b;

}

这样子操作后, call_add_times就会从栈区域进到全局变量区域,但是又能保证只对add函数可见,其他函数都调用不到。

你说,妙哉否?

我们在学习一些语言,技巧的时候,尽量要去思考它的使用场景,这样子的话,你就知道,它的每个设计,都是为了解决一类问题,也就是需求推动设计。

好了,今天就说的这里,不知道你学的开心不开心?下一节我们来说下,关于inline 关键字的用法,这个比较简单,我们下一节见!返回搜狐,查看更多

责任编辑:


http://chatgpt.dhexx.cn/article/DixLbwrb.shtml

相关文章

C语言static和extern关键字

1.static static修饰的变量,自始至终只有一块空间,当前文件才能使用,生命周期是从定义开始直到程序结束;全局变量的定义是在.c文件中,但是声明全局变量是在.h中;static:静态型,用它定…

C语言static关键字修饰变量及函数时的用法和原理

目录 一.static关键字修饰局部变量 二.static关键字修饰全局变量 三.static关键字修饰函数 一.static关键字修饰局部变量 在内存中,往往将其分为三个区块,栈区,堆区,静态区。C语言中定义的局部变量包括函数参数都存储在栈区&am…

C语言 static的使用

你知道C语言中 static 有几种用法&#xff1f; 目录 1. static 可以修饰局部变量 2. static 可以修饰全局变量 3. static 可以修饰函数 1.static 可以修饰局部变量 首先让我看看这段代码 #include<stdio.h> void test() {int a 1;a a 1;printf("%d", a);…

C语言 Static关键字的作用详解

前言&#xff1a; static 是用来修饰函数和变量的&#xff0c;可以修饰局部变量&#xff0c;全局变量以及函数 一、修饰局部变量 &#xff08;称为静态局部变量&#xff09; 来看俩段代码&#xff1a; 对于第一段代码来说&#xff0c;它循环5次&#xff0c;每次调用一下fun(…

[深度解剖C语言] --关键字 static

static ---最名不副实的关键字 目录 1.static修饰全局变量 2.static修饰函数 3.static修饰局部变量 static的作用&#xff1a; 1.static修饰全局变量 我们创建两个源文件&#xff0c;一个test.c&#xff0c;一个main.c 现在我们在test.c文件下定义一个全局变量 int g_va…

C语言中static的用法(修饰局部变量,修饰全局变量,修饰函数)

static 关键字有三种用法 static 修饰局部变量 - 静态局部变量static 修饰全局变量 - 静态全局变量static 修饰函数 - 静态函数 static 关键字的三种用法 1. static 修饰局部变量 - 静态局部变量2. static 修饰全局变量 - 静态全局变量3. static 修饰函数 - 静态函数 1. stati…

带你熟知关键字static用法——C语言(举例及通俗易懂)

引入 首先我们看两个例子&#xff1a; 例1 #include<stdio.h> void test() {int i 0;i;printf("%d", i); } int main() {int a 0;while (a < 10){test();a;}return 0; } 例2 #include<stdio.h> void test() {static int i 0;i;printf("%d…

【C语言】 Static关键字的用法和详解(太细了!!!)

文章目录 目录 前言 一、static是什么 二、static的用法 1.修饰局部变量 2.修饰全局变量 3.修饰函数 总结 前言 static在不同的语言中又有不同的使用方法&#xff0c;本文介绍的是static在C语言当中的用法。 一、static是什么 static在C语言中是关键字&#xff0c;中…

C语言中的static的用法(超级详细)

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:[云小逸的主页] &#x1f4dd;码云&#xff1a;云小逸 (YunXiaoYi003) &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;…

JQuery HTML5 验证表单

HTML5新增属性验证表单内容 <body><!-- HTML5验证的特性 &#xff1a;required"required"必填number,url,email,search....--><form action"#" method"post"><input type"search" id"uname" value&quo…

jQuery表单验证实例 / 包含用户名、密码、住址、邮箱验证

jQuery表单验证实例 / 包含用户名、密码、住址、邮箱验证 如下图 别忘了引入jQuery框架&#xff01;&#xff01;&#xff01; 话不多说直接先上jQuery部分代码&#xff1a; <script type"text/javascript">$(document).ready(function(){var tip1 "&…

jquery表单验证(jQuery表单验证插件Validation怎么下载)

如何用jquery的form插件验证表单 你好&#xff0c;插件无非就是集成所有可能出现的情况&#xff0c;通过配置来调用验证&#xff0c;比如jqueryvalidate插件&#xff0c; 插件内部实现一些非空&#xff0c;正则格式&#xff0c;邮箱&#xff0c;url等判断&#xff0c;你要做的就…

jQuery实现表单的验证

要求&#xff1a;技术要求&#xff08;htmlcssjquery&#xff09; 1. 完成页面布局&#xff08;页面布局合理、样式和图片一致、代码无误各&#xff09; 2. 用jquery验证Email地址是否有效&#xff0c;要求Email地址中必须包含符号&#xff0c;如果Email地址有效则显示”正确…

jQuery--表单校验

jQuery -- 表单校验 表单验证String对象和表单验证有关的成员正则表达式表单选择器表单验证事件和方法 表单验证 为什么要进行表单验证&#xff1f; 无论是动态网站&#xff0c;还是其他B/S结构的系统&#xff0c;都离不开表单。 表单作为客户端向服务器端提交数据的主要载体&a…

jQuery表单验证插件

表单验证插件 表单验证规则 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title><style>#myform label.error{color: #FF0000;}</style><script src"js/jquery-3.3.1.js"><…

jQuery基础之表单验证

前言 在学习jquery-validate.js时的一些的记录 正文 在使用jquery-validate.js插件时可以做一些初始化配置 在初始化jquery-validate.js对象的时候&#xff0c;将外部的一些配置和该插件内部的一些默认配置合并在一起&#xff0c;如果有相同的配置&#xff0c;前者覆盖后者…

JQuery表单校验

JQuery表单验证 常用表单主要包括&#xff1a;用户名–密码–确认密码–邮箱–验证码 初学阶段我们忽略验证码的真实性&#xff0c;仅对齐进行非空验证 表单代码 <div id"content"><div class"login_form"><div class"login_box&quo…

jQuery表单验证(Validate)使用方法

表单的校验是jQuery给页面开发者带来极大便利的功能之一&#xff0c;无论是在校大学生还是已经上班的工程师&#xff0c;都可以了解一下表单校验的基本功能。 目录 1.先来一张简单的表单2.引入需要用到的jQuery3.指定需要验证的内容4.如何自定义报错信息的位置5.如何添加其他的…

jQuery插件及表单验证

一、自定义插件 前提&#xff1a;引入jquery-3.3.1.js <script src"js/jquery-3.3.1.js" type"text/javascript"></script> 1、$.extend(对象1&#xff0c;对象2) 对象1继承对象2 /*自定义插件*/$(function(){//$extend(对象1,对象2) 对象1…

jq表单验证

<!DOCTYPE html> <html><head><title>手工实现表单验证</title><meta charset"utf-8" /><script src"scripts/jquery-1.11.3.js"></script></head><body><fieldset><legend>用户…