在学习汇编的过程中,小有所悟,遂把自己所思所想记下,以便日后查阅。

首先说说我对这个关键字的理解。static字面上就是静止的、静态的、不变的之类的意思,所以在被它修饰之后,应该也会带有这样的一些特点。事实证明也确实是这样,利用这样的特点能很方便的达到一些编程实践中所要达到的一些效果。而它的存在在本质上又有什么样的原理在里面呢?说到这,我就不得不说,学底层的东西有一点好,就是能了解原理。对于我这样的一个喜欢知根知底的人来说,确实很有吸引力。

存储角度:

在最近的汇编学习中,我了解到内存中有(但不是仅有)3中不同的区域,分别是:静态存储区域、堆和栈。然后它们有着不同的职能,而静态存储区就和我们这次要聊的static有着莫大的关联。

大家都知道,程序要先加载到内存中,才能正常工作。那有没有具体想过,程序究竟是怎么被加载到内存中的?以及,程序到底是啥?就我现在的理解,程序在存储的角度看,就是变量和函数。所以,把程序加载到内存也就是把变量和函数加载到内存。那么问题就来了,这里的变量是哪些变量呢?好吧。。其实哪种变量都有可能,我最关注的就是全局变量静态变量(被static修饰的变量

因为这两种变量是要被放到内存的静态存储区的(对,变量虽然都是变量,但存储的位置却大有不同)。所以说,从存储的角度看,全局变量和静态变量是存储在同一地方的,而且这两种变量(所占的空间)还是要写死在生成的目标可执行文件中的(对于编译型语言)。

我推断:

1.全局变量好理解,它要先于任何函数而存在,所以它不可能在栈中;而堆变量也要从函数中申请,所以在没有函数存在的前提下,存放在静态存储区的全局变量只能由目标可执行文件提供。

2.静态变量则是在函数执行完毕从栈中弹出后依然存在的,所以它肯定不在栈上,而它又不是动态申请来的,所以也不在堆上,那从存储角度讲,它的存在其实和函数是没有关系的。所以要加载它只能从目标可执行文件中来。

所以,从存储的视角来看,static变量与全局变量并无差别。

逻辑角度:

这里有两个概念要说明一下,就是作用域生存期

一个变量的作用域就是能访问这个变量的范围;而一个变量的生存期则是我能访问这个变量的时期或者说时机。

这样就有了至少四种组合:1.全局可访问+局部(函数内)生存期 2.全局可访问+全局生存期 3.局部可访问+局部生存期 4.局部可访问+全局生存期

第1种可能性简直是一个逆天的存在。。。单线程的程序同一时间不可能跑两个函数,所以这样的做法毫无意义。所以这种可能性根本不存在。

第2种可能性就是全局变量。

第3种可能性就是栈变量,也就是函数的局部变量。

而第4种可能性就是我们今天的重头戏,被static修饰的静态变量。(其实我暗想,堆变量也能在十分别扭的操作下达到这种效果,但是实在不是常规途径)

全局生存期对全局变量来说理所当然,但是对一个作用域是局部的函数内部的变量来说意味着什么呢?这意味着函数结束从栈中被弹出后,变量的值还存在

这就是static的语义所在——不变的,这里的不变指的是变量的生存状态不变。哈哈,中二一点其实也可以叫它作“不死变量”。

那也许有人会问:这有什么用呢?当然有用,我最感兴趣的一个作用是:函数可以存住东西了。函数终于不再那么的“动态”了,开始有点“静态”的影子了。

举个例子的话,比如我要从一个字符串中往外一个一个地取字符,运用了static修饰符,我就可以优雅地每调用一次一个函数就取到一个直达取完。C语言的话我可以写成下边的样子。

 #include <stdio.h>

 char getChar(char *str){
static int index = ;
char result = str[index];
index++; return result;
} int main(int argc, char const *argv[]){
char *str = "Hello World!"; char c;
while( (c=getChar(str)) != '\0' ){
putchar(c);
} return ;
}

这样的一个好处是我可以不用破坏原字符串而且是很方便地用一个独立的函数,实现了所想即所得。

全局生存期是它们的共同点,而不同则在于作用域的不同,这也是static的作用所在。全局变量,在所有函数中均可访问,那这样就会产生安全性问题,导致在用这个变量的时候不能确保它的值只被本函数所控制。这就是所谓的封装性差。而static修饰符恰能解决这一点,由于被它修饰的变量是函数的局部变量,导致它的作用域仅在这个函数内,这样我们便可安心大胆的断定,这个变量的值只由本函数控制。

而在像Java这样的语言中,却不允许用static修饰局部作用域的变量。我想可能是因为已经能有其它的方式来表达类似的语义了,虽然不完全一样。而且到了面向对象编程的时候,我们完全可以换另一种思维来考虑问题,所以也不是那么的需要这样的函数设计方式了。在Java中,static的含义与C语言中大不相同。我们目前只说了“不死变量”这一种语义,就这一点Java是没有的,可它却有另外的含义。

未完待续...

浅谈static其一之不死变量的更多相关文章

  1. 浅谈JS中 var let const 变量声明

    浅谈JS中 var let const 变量声明 用var来声明变量会出现的问题: 1. 允许重复的变量声明:导致数据被覆盖 2. 变量提升:怪异的数据访问.闭包问题 3. 全局变量挂载到全局对象:全 ...

  2. 浅谈static关键字的四种用法

    1.修饰成员变量 在一个person类中,一个成员变量例如 String name,当new2个person()对象时候,这2个对象在堆的位置是不同的,给name赋值张三.李四,这两个对象的name是 ...

  3. 浅谈Static

    A: 使用场景 static可以修饰成员变量和成员方法. 什么时候使用static修饰成员变量? 加static修饰成员的时候,这个成员会被类的所有对象所共享.一般我们把共性数据定义为静态的变量 什么 ...

  4. 浅谈Static关键字

    1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ...

  5. 浅谈STM32L071硬件I2C挂死

    STM32的IIC问题一直存在,在网上也被很多人吐槽,然而FAE告诉我,硬件IIC的问题在F1,F3,F4系列单片机存在,而在L0上已经解决了,然而这几天调试加密芯片和显示芯片,都是IIC芯片,却再一 ...

  6. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

  7. 【原创】浅谈指针(十二)关于static(上)

    0.前言 这个系列基本上是一月一更到两月一更 今天写一篇关于static的,内含大量干货,做好准备 1.基础知识的回顾 1.1.内存的种类 一般来说,我们之前已经讲过的变量(或者说是内存)可以大体分为 ...

  8. 浅谈 PHP 变量可用字符

    原文:浅谈 PHP 变量可用字符 先来说说php变量的命名规则,百度下一抓一大把:(1) PHP的变量名区分大小写;(2) 变量名必须以美元符号$开始;(3) 变量名开头可以以下划线开始;(4) 变量 ...

  9. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

随机推荐

  1. 数据结构与算法 —— 链表linked list(03)

    继续关于linked list的算法题: 删除排序链表中的重复元素 给定一个排序链表,删除所有重复的元素使得每个元素只留下一个. 案例: 给定 1->1->2,返回 1->2 给定  ...

  2. Apache Flink 分布式执行

    Flink 的分布式执行过程包含两个重要的角色,master 和 worker,参与 Flink 程序执行的有多个进程,包括 Job Manager,Task Manager 以及 Job Clien ...

  3. MySQL5.7.21解压版安装详细教程以及一些问题的解决

    笔者是最近玩mysql的时候玩坏了,想写点东西记录下.我安装的是MySQL5.7.21,安装之后没有my.ini文件. 遇到了2个问题,一是mysql服务启动不了,被my.ini整了,二是root密码 ...

  4. nginx反向代理二级域名注意事项

    摘要 本文介绍了利用nginx实现多域名和多站点的绑定的方法及相关注意事项.您也可以只看本文的标题或红色标注部分.☺ 1.应用场景 我们经常会遇到在同一台服务器建立多个Web站点的情况,普遍的做法是为 ...

  5. uvalive 3602 DNA Consensus String

    https://vjudge.net/problem/UVALive-3602 题意: 给定m个长度均为n的DNA序列,求一个DNA序列,使得它到所有的DNA序列的汉明距离最短,若有多个解则输出字典序 ...

  6. 通过数据绑定控制WPF动画启动,WPF动画开始

    1.主要代码: <ControlTemplate.Triggers> <DataTrigger Binding="{Binding Open,RelativeSource= ...

  7. web开发 c/s结构 和 b/s结构

    web开发 c/s结构 和 b/s结构 c/s结构 --client/server 客户端/服务器机构 如qq b/s结构 -- browser/server 浏览器/服务器结构 如网站 mvc设计 ...

  8. PhantomJS命令行选项

    支持命令行选项有: --help或-h列出所有可能的命令行选项.立即停止,不会运行一个脚本作为参数传递. --version或-v打印的版本PhantomJS.立即停止,不会运行一个脚本作为参数传递. ...

  9. ps图层的基本使用

    图层的使用 图层的基本使用一:复制,选择多个,背景图上添加图片,同时移动多个图层 复制图层:图层里的内容位置会变化,而拷贝的图层,图层里的位置不变,跟原来的图层一样 选择多个图层:shift选中多个图 ...

  10. 如何在现有的 Web 应用中使用 ReactJS

    原文:How to Sprinkle ReactJS into an Existing Web Application 译者:nzbin 当我们学习一项新技术,可能是一个 JavaScript 框架, ...