从汇编看c++中函数里面的static关键字的使用说明
下面从汇编语言看其原理.
void add() {
static int i = 1;
i++;
}
int main() {
add();
}
; 5 : int main() {
push ebp
mov ebp, esp
; 6 : add();
call ?add@@YAXXZ ; 调用add
; 7 :
; 8 : }
xor eax, eax
pop ebp
ret 0
; 1 : void add() {
push ebp
mov ebp, esp
; 2 : static int i = 1;
; 3 : i++;
mov eax, DWORD PTR ?i@?1??add@@YAXXZ@4HA;取变量i的值
add eax, 1;执行加法
mov DWORD PTR ?i@?1??add@@YAXXZ@4HA, eax;存变量i的值
; 4 : }
pop ebp
ret 0
可以看,不论是main函数,还是add函数里面,我们都看不到为i分配存储空间,也就是说,i不在他们的调用栈里面。
_DATA SEGMENT
?i@?1??add@@YAXXZ@4HA DD 01H ; 为变量i声明存储空间
; Function compile flags: /Odtp
_DATA ENDS
这条语句为i预先分配了存储空间,并且在上面两个函数汇编码的外面定义。因此,函数里面由static关键字修饰的变量生命期存在于整个程序里面,但是,可见性依然只在add函数里面,在外面访问不到.
相关推荐
-
浅谈C/C++中的static与extern关键字的使用详解
一.C语言中的static关键字在C语言中,static可以用来修饰局部变量,全局变量以及函数.在不同的情况下static的作用不尽相同.(1)修饰局部变量一般情况下,对于局部变量是存放在栈区的,并且局部变量的生命周期在该语句块执行结束时便结束了.但是如果用static进行修饰的话,该变量便存放在静态数据区,其生命周期一直持续到整个程序执行结束.但是在这里要注意的是,虽然用static对局部变量进行修饰过后,其生命周期以及存储空间发生了变化,但是其作用域并没有改变,其仍然是一个局部变量,作用域仅
-
C++的static关键字及变量存储位置总结
今天看博文时,看到了c++的static关键字的一些总结,还涉及到了一些代码的存储位置,为了有时间的时候能够看一下,还是自己把它给摘抄下来吧. C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 一.面向过程设计中的static 1.静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量.我们先举一个静态全局变量的例子,如下: 复制代码 代码
-
static关键字的作用详解
(1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 复制代码 代码如下: char a = 'A'; // global variablevoid msg() { printf("Hello\n"); } 下面是main.c的内容 复制代码 代码如下: int main(void){
-
关于C/C++中static关键字的作用总结
1.先来介绍它的第一条也是最重要的一条:隐藏.(static函数,static变量均可)当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.举例来说明.同时编译两个源文件,一个是a.c,另一个是main.c. 复制代码 代码如下: //a.cchar a = 'A'; // global variablevoid msg(){ printf("Hello\n");} 复制代码 代码如下: //main.c int main
-
从汇编看c++中函数里面的static关键字的使用说明
下面从汇编语言看其原理. 下面是c++源代码: 复制代码 代码如下: void add() { static int i = 1; i++;}int main() { add(); } 下面是main对应的汇编码 复制代码 代码如下: ; 5 : int main() { push ebp mov ebp, esp ; 6 : add(); call ?add@@YAXXZ ; 调用add ; 7 :
-
从汇编看c++中的多态详解
在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的一项重要功能就是初始化vptr指针,这是保证多态性的关键步骤. 构造函数初始化vptr指针 下面是c++源码: class X { private: int i; public: X(int ii) { i = ii; } virtual void set(int ii) {//虚函数 i = ii; } }; int main() { X x(1); } 下面是对应的main函数汇编码: _main PROC ; 16 : in
-
C#中const,readonly和static关键字的用法介绍
如果有一个值不太会变化,我们经常使用const和readonly,这2者有何不同呢?有时候,我们也会在readonly之前加上关键字static,这又意味着什么呢? const const默认是静态的,可以通过"类名.字段名"来访问. const变量只能在声明的时候赋值,不能在构造函数中为const类型变量赋值. 一旦程序集被编译,const变量会被写进程序集的IL代码中.如果想修改const变量值,必须在修改值后再重新生成程序集. const是编译期变量 public class T
-
从汇编看c++中多态的应用
在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的一项重要功能就是初始化vptr指针,这是保证多态性的关键步骤.构造函数初始化vptr指针下面是c++源码: 复制代码 代码如下: class X {private: int i;public: X(int ii) { i = ii; } virtual void set(int ii) {//虚函数 i = ii; }};int main() { X x(1);} 下面
-
从汇编看c++中默认构造函数的使用分析
c++中的源程序: 复制代码 代码如下: class X {private: int i;}; int main() { X x;} 上面的类X没有定义构造函数,仅仅有一个int i. 下面为其汇编程序: 复制代码 代码如下: ; 7 : int main() { push ebp;ebp为一个寄存器,总是指向一个函数调用堆栈的栈底,作为基址,用偏移量来访问该调用栈上的变量,但这里没有任何变量要访问,因此不起作用 mov ebp, esp;这两句的作用是为了
-
从汇编看c++中extern关键字的使用
在c++中,extern关键字用来声明变量和函数,在声明函数的时候,有和没有extern的效果一样,即下面两条语句具有同样的效果: 复制代码 代码如下: extern void fun(); void fun(); 但是对于变量,有和没有extern就有区别,当有extern时,只是告知编译器存在这个变量,编译器并不为该变量分配存储空间,即真正的声明:若没有extern,则在声明的同时,编译器也为该变量分配存储空间. 下面是有extern的情形时的c++源码: 复制代码 代码如下: int ma
-
从汇编看c++中变量类型的深入分析
全局变量的生命期和可见性是整个程序的运行期间,下面就来用汇编来看一下实际情况: c++源码: 复制代码 代码如下: int i = 2;//全局变量 int main() { int j = i;} 下面是汇编代码: 复制代码 代码如下: PUBLIC ?i@@3HA ; i_DATA SEGMENT?i@@3HA DD 02H ; 全局变量i内存空间_DATA ENDSPUB
-
从汇编看c++中引用与指针的使用分析
首先是引用情形下的c++源码: 复制代码 代码如下: void add(int a, int b, int&c) { c = a + b;} int main() { int a = 1; int b = 2; int c = 0; add(a, b, c); } 下面是main对应的汇编码: 复制代码 代码如下: ; 6 : int main() { push ebp mov ebp, esp sub esp, 12
-
浅谈numpy 函数里面的axis参数的含义
前言 numpy支持对矩阵和数组进行运算,因此很多numpy的很多运算都需要指定操作的维数参数axis(当然这些axis都有带默认值的),本博客以numpy.sum求和函数为例,具体分析axis参数不同取值下的含义. 先说结论 设 numpy.sum的输入矩阵为a. numpy.sum的返回矩阵为rst. 则矩阵a的形状为:sp=numpy.shape(a),例如sp=[m,n,p,q···] rst的形状为将sp的第axis个元素设为1,即: sp'=sp sp'[axis]=1 numpy.
-
从汇编看c++的默认析构函数的使用详解
c++中,如果没有为一个类提供析构函数,那么编译器会为这个类提供默认的析构的函数.由于析构函数的功能和构造函数相反,因此和默认的构造函数类似,编译器也会提供无用的默认的析构函数,和非无用的析构函数.两者的分析情况一样(对于默认的构造函数分析,请参看<从汇编看c++中默认构造函数的使用分析>).并且编译器会提供非无用的默认析构函数情形和默认构造函数类似: 1 类含有虚成员函数(类继承自虚基类或者继承的基类含有虚成员函数,也属于这种情况) 2 类继承自一个基类,基类含有自定义析构函数(如果基类没有
随机推荐
- 如何处理包含javascript语句时的间隔符?
- jQuery实现鼠标跟随提示层效果代码(可显示文本,Div,Table,Html等)
- Oracle数据库的十种重新启动步骤
- js判断数据类型如判断是否为数组是否为字符串等等
- Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
- asp.net(vb)实现金额转换成大写的函数
- 封装的android监听手指左右滑动屏幕的事件类分享
- 基于MySQL到MongoDB简易对照表的详解
- 实例讲解Android中的AIDL内部进程通信接口使用
- Android WebView那些坑之上传文件示例
- Android实现从本地图库/相机拍照后裁剪图片并设置头像
- 运维管理器Fabric使用方法
- 1975-1985年出生的人,值得收藏和回味的帖子
- JavaScript中Form表单技术汇总(推荐)
- MessageBox的Buttons和三级联动效果
- JavaScript数组排序reverse()和sort()方法详解
- 详解Vue-cli webpack移动端自动化构建rem问题
- numpy库与pandas库axis=0,axis= 1轴的用法详解
- 深入理解JVM之类加载机制详解
- Python爬取知乎图片代码实现解析