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

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

1 不污染全局符号

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

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

代码段

数据段

BSS段



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

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

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

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

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

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

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

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

hello.c

我们这里看下,没有#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 -s add.o ,看到信息,add前面有个Bind的值是GLOBAL,这个就是说明,add是在可以让其他.o链接时候去查找的一个符号,它的类型是func函数。

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

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

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

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

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

hello.c 改成

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

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

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

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

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

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

而如果说你让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 关键字的用法,这个比较简单,我们下一节见!

喜欢,帮忙转发~~

~~ end not end ~~

热门文章

零基础新手自学Python编程教程入门精通学习资料网站大全

自学编程C语言不迷路,我私藏的书单分享给你!

零基础新手学习算法Leetcode刷题指南

程序员码农IT工程师自学编程计算机入门进阶学习网站大全

程序员面试题宝典以及相关书籍下载!

计算机类常用电子书整理大全

职场老鸟,互联网十年从业生涯,分享 [Java,Python,安卓,AI,爬虫] 技术文章,学习资料, 热点趣闻等。关注回复 1024 Python 电子书大全 面试资料,给你一份私藏的程序员好礼,永远更新中!赶紧来关注哦!

我的微信 code_gg_boy 。

C语言 static 声明静态变量?大佬原来用它干这事!相关推荐

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

    原标题:C语言 static 声明静态变量?大佬原来用它干这事! C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它! 高手在写代码的时候,会特别注重的一点就是,对外的方法对外,不对外的方法和数据,都 ...

  2. 浅谈C语言static关键字 静态变量 函数

    目录 static对变量修饰 局部变量 全局变量 函数 static对变量修饰 局部变量 普通局部变量存储于进程栈空间,使用完毕会立即释放. 静态局部变量存储于进程的全局数据区,即使函数返回,它的值也 ...

  3. c语言静态函数调用静态变量_C语言中的静态变量和函数

    c语言静态函数调用静态变量 C中的静态变量 (Static Variables in C) Basically, when static variables are declared, they cr ...

  4. C语言中的静态变量和静态函数

    C中的静态变量 基本上,声明静态变量时,它们仅创建它们的单个副本,也称为类变量 .它们保留在相应范围内分配的值,并且不会在其新范围内再次初始化变量. 静态变量在代码执行期间保留在内存空间中. 静态变量 ...

  5. c语言指针访问 静态变量_使用C中的指针访问变量的值

    c语言指针访问 静态变量 As we know that a pointer is a special type of variable that is used to store the memor ...

  6. 类内如何声明静态变量,常量问题

    类内声明静态变量: // static_variable.h class a {static int var; };// static_variable.cpp #include "stat ...

  7. static(静态变量,方法)

    static(静态变量,方法) 文章是作者面向对象文章的单独拆分如果存在阅读不连续性请参考下文 Java面向对象 完整代码 是什么? 静态的变量与方法不属于对象,而是属于类 我们常说的类变量.类方法( ...

  8. C++之static,静态变量

    目录 1.为什么要用静态变量 2.全局变量 3.静态局部变量 4.静态数据成员的空间开辟 5.静态数据成员 6.释放 7.总结 1.内存: 2.初始化: 3.最大的优点: 4.指针: 5.释放时机: ...

  9. C语言static声明有什么用途?使用全局变量的优点和副作用是什么?

    (1) static声明有什么用途 (请至少说明两种)?static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别? 1.限制变 ...

最新文章

  1. matlab模块 python,Matlab 和Python结合使用
  2. linux安装web服务器httpd,Linux_linux构建动态WEB服务器安装篇,基本配置 安装web服务器:httpd-2. - phpStudy...
  3. python的socket模块_Python socket模块方法实现详解
  4. python远程桌面控制_手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
  5. SSM前后端分离及跨域
  6. linux系统上传代码到gitlab服务器
  7. 圆的交点 (Python)
  8. 遍历二叉树的基本思路
  9. ubuntu目录结构
  10. 系统常用 Intent 合集
  11. 必应词典的使用和分析
  12. 【Python_绘图】堆积柱形图
  13. shine your way
  14. sql语句左连接时的ON AND用法
  15. SIMULIA-达索系统一体化仿真解决方案
  16. 文件压缩c语言程序代码,C语言程序设计之RLE压缩解压算法
  17. 消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(二)
  18. 家用洗地机哪个牌子质量最好?高性价比家用洗地机推荐
  19. 文本样式设置/盒子模型学习笔记
  20. 使用ANTLR和Go实现DSL入门

热门文章

  1. 大唐杯5G练习题(二)
  2. 两位数求和(xhh)
  3. 使用Python绘制圣诞树教程(附源代码)
  4. 108.【RabbitsMQ】
  5. Java封装继承多态练习题
  6. DH 加密算法的使用
  7. 计算机小学数学辅助教学缺点及对策 论文,小学数学第二学段图形与几何领域的作业设计研究...
  8. APP运营推广,如何做到“饱和攻击”
  9. html+css+js简单实现图片轮播效果
  10. pytorch distiller filter channel剪枝