(C/C++学习笔记) 九. 变量的存储类型
九. 变量的存储类型
● 变量的存储类型(见附页)
● 注释
①对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。 ②"static"的含义不是指存储方式,而是指变量的作用域仅局限于本文件,一个函数内部的变量, 如果有关键字static修饰, 那么在函数调用结束时, 该静态变量的值不会消失。 另外,函数前加static使得函数成为静态函数,指函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数是否会与其它文件中定义的的函数同名。 static函数与普通函数的区别是:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。 ③⑤ 在函数体内定义的静态变量为静态局部变量,在函数体外定义的静态变量为全局局部变量。 ④The extern keyword is used in functions to declare a static external variable that is defined elsewhere.
● 全局变量和静态全局变量都属于静态存储类。生存期都是程序的一次执行,定义和初始化都是在程序编译时进行,其初始化只有一次。若没有初始化,则自动赋以0(数值型)或'\0' (字符型)。 种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。 ※变量的分类方法 第一种:根据数据类型划分 ●可以从时间和空间两个不同的角度来描述变量的特性:生存期,作用域 第二种:根据变量的作用域——全局变量(在函数体外(包括主函数)定义的变量)、局部变量(在函数体内(包括主函数)定义的函数) 第三种:根据变量的生命期(与变量的存储方式相关)——静态存储变量、动态存储变量 ●变量的存储方式可分为:"静态存储"和"动态存储"两种。 1. 静态存储变量(NP):在变量定义时就分配存储空间并一直保持不变,直至整个程序结束。典型的例子是全局变量。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量(static variable),例如外部变量(extern variable)虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 2. 动态存储变量: 在变量定义时不分配存储空间, 在程序执行过程中,使用它时才分配内存空间,使用完毕立即释放。典型的例子是局部 变量,函数的形式参数就是一种局部变量(还有其它任何在函数中定义的变量),在函数定义时并不为之分配存储单元,只是在函数被调用时, 才予以分配,函数调用完后立即释放。如果一个函数被反复调用,则反复地分配、释放形参变量的存储单元。 第四种:根据作用域和生命期——auto变量、static变量、register变量、extern变量。 第五种:同样根据作用域和生命期——全局变量、静态全局变量、静态局部变量、局部变量(没有动态全局变量和动态局部变量) ※ 按存储区域分:1. 全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域 2. 局部变量存放在内存的栈区(除了静态局部变量) 按作用域分: 1. 全局变量在整个工程文件内都有效 2. 静态全局变量只在定义它的文件内有效 3. 静态局部变量只在定义它的函数内有效,并且程序仅分配一次内存,函数返回后,该变量不会消失 4. 局部变量在定义它的函数内有效,但是函数返回后失效。 ● 1. 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用 extern 关键字再次声明这个全局变量。 2. 局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结 束后,变量被撤销,其所占用的内存也被收回。 3. 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对 所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见(静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它)。 4. 静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里, 即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。 //示例 static int a,b; //如果,此时在一个函数体内定义变量a,b, 那么它们是静态局部变量,如果在函数体外,那么它们是静态全局变量 auto char c1,c2; //c1,c2为自动字符变量 static int a[5]={1,2,3,4,5}; //a为静态整型数组,,并未其初始化; 它有可能是局部的,也有可能是全局的 register int a=1; //定义一个寄存器整型变量,并未其初始化 //变量a不是保存在内存上,而是直接存储在CPU中的寄存器中 extern int x,y; // x,y为外部整型变量 |
● 内存四区
内存四区 Four areas of application memory (app memory)/RAM |
※ 对于"全局区",有的资料将以区称为"数据区(data area)",包括静态区(全局区)和常量区 ※ 有的资料还有内存五区的说法: ● BSS是英文Block Started by Symbol(以符号开始的块)的简称。BSS段属于静态内存分配。 ※ 再看下面一个详细图: |
●栈区: stack 栈区是由编译器自动分配和释放,存放函数的参数值、局部变量的值等。 ●堆区:heap 堆区由程序员自行申请分配和释放,比如需要 malloc()函数来申请,free()函数来释放。 ●数据区:data 数据区主要包括:静态区/全局区,常量区, 静态区(static)/全局区(global): 全局变量和静态变量是存储在一块的,即都在静态区(有的资料又称为"全局区") 1. 初始化的全局变量和初始化的静态变量是在一块的。 2. 未初始化的全局变量和未初始化的静态变量是在相邻一块。 常量区: 数据只读,常量字符串就放在这里。 ●代码区:code 代码区是存储编译后的可执行代码,机器码 例如: int a=1; //a在栈区 char s[]="123"; //s在栈区,"123"在栈区,其值可以被修改 char *s="123"; //s在栈区,"123"在常量区,其值不能被修改 int *p=new int; //p在栈区,申请的空间在堆区(p指向的区域) int *p=(int *)malloc(sizeof(int)); //p在栈区,p指向的空间在堆区 static int b=0; //b在静态区 |
● 全局变量, 静态全局变量, extern变量举例
全局变量, 静态全局变量, extern变量举例 工程test源文件夹内有两个源文件: 1.cpp和2.cpp |
//1.cpp #include <iostream.h> int a =1; //定义一个全局变量 static int b=2; //定义一个静态全局变量,只能在本文件中使用 //2.cpp #include <iostream.h> extern int a,b; int main() { a=3; //改变外部变量a的值 cout<<"a="<<a<<endl; //b=4; //cout<<"b="<<b<<endl; 编译器会报错,因为b是另一个文件的静态全局变量 return 0; } //也可以在主函数内引用外部变量 //2.cpp #include <iostream.h> int main() { extern int a; a=3; cout<<"a="<<a<<endl; return 0; } |
● 静态局部变量案例
#include <iostream> using namespace std; int f(int a) //定义f函数,a为形参 { auto int b=0; //定义b为自动变量 static int c=3; //定义c为静态局部变量 b=b+1; c=c+1; return a+b+c; } int main( ) { int a=2,i; for(i=0;i<3;i++) cout<<f(a)<<" "; cout<<endl; return 0; } |
(C/C++学习笔记) 九. 变量的存储类型的更多相关文章
- C++ Primer 学习笔记_5_变量和基本类型(续2)
变量和基本类型 七.枚举 枚举不但定义了整数常量集,并且还把它们聚集成组. 枚举与简单的const常量相比孰优孰劣, 通过以下一段代码. 一看便知: enum {input, output, a ...
- 02.第二章_C++ Primer学习笔记_变量和基本类型
2.1 基本内置类型 2.1.1 算术类型 算术类型包括两类:整型和浮点型 2.2 变量 2.3 复合类型 2.4 const限定符 2.5 处理类型 2.6 自定义数据结构
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- Go语言学习笔记九: 指针
Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...
- go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)
目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...
- ES6学习笔记之变量的解构赋值
变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...
- C语言中变量的存储类型
在C语言中,对变量的存储类型说明有以下四种: auto 自动变量register 寄存器变量extern 外部变量static 静态变量 自动变量和寄存器变量属于动态存储方式,外部变量和静态变 ...
随机推荐
- [Redis] - 高并发下Redis缓存穿透解决
高并发情况下,可能都要访问数据库,因为同时访问的方法,这时需要加入同步锁,当其中一个缓存获取后,其它的就要通过缓存获取数据. 方法一: 在方法上加上同步锁 synchronized //加同步锁,解决 ...
- UVa 10817 校长的烦恼
https://vjudge.net/problem/UVA-10817 题意: 某校有m个教师和n个求职者,需讲授s个课程,已知每人的工资c和能教的课程集合,要求支付最少的工资使得每门课都至少有两名 ...
- C# 获取文件夹下的所有文件夹及其文件
//获得当前文件夹下所有文件夹 string path = "D://文件夹"; string[] dirstr = Directory.GetDirectories(path); ...
- win7(64)未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序
注:本文为个人学习摘录,原文地址:http://blog.163.com/rihui_7/blog/static/2122851432013627103337825/ 1.以前在win7 64位系统上 ...
- nginx 80 端口默认被占用
/etc/nginx/sites-enabled,修改该目录下的default文件, 将默认端口号80改为其他端口号, /etc/nginx/nginx.conf 文件配置里的80端口就会生效
- Django部署生产环境,静态文件不能访问404,以及图片不能访问403
部署环境的搭建请看此博客https://blog.csdn.net/anifans9350/article/details/80145535 查看nginx.conf 文件, nginx文件(etc/ ...
- SQLServer 中的SYSPROCESSES表
性能测试的时候对SQLserver DB中的CPU,io,内存进行监控 可以通过系统进程表查看资源使用情况 注意要有master权限 select top 10 * from SYSPROCESSES ...
- bash Shell 中如何实现条件判断之if判断
http://blog.51cto.com/lovelace/1211353 bash中如何实现条件判断?条件测试类型: 整数测试 字符测试 文件测试 一.条件测试的表达式: ...
- 《剑指offer》第三十四题(二叉树中和为某一值的路径)
// 面试题34:二叉树中和为某一值的路径 // 题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所 // 有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. #i ...
- 《剑指offer》第六题(重要!从尾到头打印链表)
文件main.cpp // 从尾到头打印链表 // 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. #include <iostream> #include <sta ...