C/C++:static用法总结
- 前言:static是C/C++中一个很重要的关键字,最近阅读了很多博客和资料,遂在此对自己的学习笔记进行简单的总结并发表在这里
一、C语言中的static
• 静态全局变量:在全局变量之前加上关键字static,该全局变量就被定义成了一个静态全局变量
特别注意:
1.静态全局变量在内存中的存储位置:静态区(全局区)。 [注]:静态区(全局区)在整个程序运行期间都存在
2.静态全局变量的初始化:未经初始化的静态全局变量会被程序自动初始化为0。 [注]:在C语言中,未经初始化的全局变量的值是任意的;而在C++中,未经初始化的全局变量也会被程序自动初始化为0
3.全局变量和静态全局变量的存储方式是一样的,但不同的是全局变量在整个源代码中都是可以使用的,而静态全局变量只能在当前文件中使用。比如一个程序有3个文件a.cpp、b.cpp和c.cpp,如果在文件a.cpp中定义了一个全局变量x,那么变量x在文件a.cpp、b.cpp和c.cpp中都可以使用;但如果在文件a.cpp中定义了一个静态全局变量y,那么变量y只能在文件a.cpp中使用文件b.cpp和文件c.cpp都不可以使用该静态全局变量y
源文件file1.cpp:
- // 文件file1.cpp
- int value1=;//全局变量value1
- static int value2;//静态全局变量value2,默认初始化为0
- ......
源文件file2.cpp:
- // 文件file2.cpp
- extern int value1; //成功:期望使用文件file1中定义的全局变量value1
- extern int value2; //错误:期望使用文件file1中定义的静态全局变量value2,但value2是static类型,只能在file1中使用,无法被其他文件使用
- ......
4.使用静态全局变量的好处:
a.将一个全局变量定义为静态全局变量,相当于让该全局变量对该程序的其他源文件进行了“隐藏”,也就是说该静态全局变量只能在定义它的源文件中使用,而程序的其他源文件则无法访问该变量
b.程序中的其他源文件中可以使用与该静态全局变量同名的变量,而不会发生冲突
5.在C/C++程序中,如果一个全局变量仅仅在单个源文件中使用,则可以将该全局变量修改为静态全局变量,以降低模块间的耦合度
• 静态局部变量:在局部变量之前加上关键字static,该局部变量就被定义成了一个静态局部变量
特别注意:
1.静态局部变量在内存中的存储位置:静态区(全局区)。[注]:普通局部变量在内存中的存储位置为栈区
2.静态局部变量的初始化:未经初始化的静态局部变量会被程序自动初始化为0。[注]:在C/C++中,未经初始化的普通局部变量值是任意的
3.static并没有改变局部变量的作用域。换句话说就是静态局部变量的作用域仍是局部作用域,当定义它的函数或语句块结束的时候,其作用域也就随之结束。 [注]:与之相反,static改变了全局变量的作用域(在声明它的文件之外是不可见的)
4.static虽然没有改变局部变量的作用域,但它改变了局部变量在内存中的存储位置(而static修饰的全局变量在内存中的存储位置则没有被static改变),即从原来的栈区中存放改变为静态区(全局区)中存放。因此静态局部变量在离开其作用域时,并没有像一般局部变量那样被销毁,而是仍驻留在内存中的静态区(全局区)中,直到程序结束,只不过在其离开自己的作用域时,我们无法再对其进行访问。
- #include<iostream>
- using namespace std;
- int count=;
- int fun(){
- static int count=;
- return count--;
- }
- int main(){
- cout<<"Global\tLocal Static"<<endl;
- for(int i=;i<=;i++){
- cout<<" "<<count++<<"\t "<<fun()<<endl;
- }
- return ;
- }
5.在C/C++中,如果全局变量仅有单个函数访问,则可以将该全局变量改为该函数的静态局部变量,以降低模块间的耦合度
• 静态函数:在函数的返回值类型前加上关键字static,该函数就被定义成了一个静态函数
特别注意:
1.和静态全局变量相似,静态函数只能在声明它的源文件中可见,而不能被该程序的其他源文件所使用。
源文件file1.cpp:
- //文件file1.cpp
- ......
- extern void fun1(){......} //定义函数fun1
- static void fun2(){......} //定义静态函数fun2
- ......
源文件file2.cpp:
- //文件file2.cpp
- ......
- extern void fun1();//成功:期望使用文件file1.cpp中的函数fun1
- extern void fun2();//错误:期望使用文件file1.cpp中的静态函数fun2,但fun2是static类型函数,只能在file1中使用,无法被其他文件使用
2.使用静态函数的好处:
a.在该程序的其他源文件中可以定义和使用与该静态函数同名的函数,而不会发生冲突
b.将一个普通函数定义为函数,相当于让该函数对该程序的其他源文件进行了“隐藏”,也就是说该静态函数只能在定义它的源文件中使用,而程序的其他源文件则无法调用该函数。
c.静态函数会被自动分配在一个一直使用的存储区域,直到程序结束。这样避免了普通函数在调用时的进栈出栈操作,从而提高程序的运行速度
• 总结:static在C语言中的作用:
——隐藏功能:static修饰的全局变量和普通函数只能在定义它们的源文件中使用,相当于对程序中的其他源文件进行了隐藏
——默认初始化功能:static修饰的变量,不管是全局变量还是局部变量,在用户没有显式初始化它们的条件下,系统都会将他们默认初始化为0
——延长“寿命”功能:static修饰的局部变量存储在内存的静态区(全局区)而非栈区,而静态区中存储的内容只会在程序结束时被OS释放,因此当static修饰的局部变量离开自己的作用域时,其不会像一般局部变量那样被系统销毁,而是一直驻留在系统的内存中,直到程序结束。
二、C++中的static
• 静态数据成员:自定义类中被static修饰的成员变量
特别注意:
1.静态数据成员在内存中的存储位置:静态区(全局区)
2.使用:
- 语法:类名::静态数据成员名
3.静态数据成员属于类。换句话说就是类的静态数据成员为其所有对象所共享,不管该类有多少对象,静态数据成员只有一份存储于公共的内存中
- #include<iostream>
- #include<string>
- using namespace std;
- class Student{
- public:
- static int count;//记录该类的对象的个数
- Student(){
- count++;
- }
- Student(string name,int age):Name(name),Age(age){
- count++;
- }
- ~Student(){
- count--;
- }
- private:
- string Name;
- int Age;
- };
- 20 int Student::count=0; //对count进行初始化
- int main(){
- Student stu1("Tomwenxing",);
- Student stu2("Ellen",);
- Student stu3("Jack",);
- cout<<"Student类的对象的个数:"<<Student::count<<endl;
- return ;
- }
• 静态成员函数:自定义类中被static修饰的成员函数
特别注意:
1.在C++的自定义类中,一个常规的成员函数声明往往意味着:
• 该成员函数能够访问其所在类的私有部分
• 该成员函数位于其所在类的作用域之中
• 该成员函数必须由一个对象去激活从而被调用(通过this指针来实现)
如果将该类的一个成员函数声明为static,则可以只让它拥有前两种性质
2.使用:
- 语法1:类名::静态成员函数名
- 语法2:对象名.静态成员函数名
3.和静态数据成员一样,静态成员函数也属于类,即类的静态成员函数为其所有对象所共享。
4.类中的普通成员函数既可以访问一般成员变量,也可以访问静态数据成员;而类中的静态成员函数只能访问类中的静态数据成员。
[解释]:编译器在编译程序中的自定义类时,会在类中的每个普通成员函数中插入this指针,而对static修饰的静态成员函数则不会插入this指针。由于静态成员函数中没有this指针,因此静态成员函数无法在其函数体内访问非静态数据成员;相反,由于静态数据成员属于类而非特定对象,故不需要this指针也可以在函数体内访问静态数据成员,因此不管是普通成员函数还是静态成员函数,都可以在其函数体内访问静态数据成员。
5.同理,普通成员函数中可以调用静态成员方法,而静态成员方法中不能调用普通成员函数
- #include<iostream>
- #include<string>
- using namespace std;
- class Student{
- public:
- static int count; //静态数据成员
- Student(){
- count++;
- }
- Student(string name,int age):Name(name),Age(age){
- count++;
- }
- ~Student(){
- count--;
- }
- void show1();
- static void show2();
- private:
- string Name;
- int Age;
- };
- int Student::count=0; //对count进行初始化
- /*
- 25 编译器对成员函数show1的改写:
- 26 void Student::show1(Student* const this){
- 27 cout<<"Name:"<<this->Name<<endl;
- 28 cout<<"Age:"<<this->Age<<endl;
- 29 cout<<"Count:"<<count<<endl;
- 30 show2();
- 31 */
- void Student::show1(){
- cout<<"调用了方法show1"<<endl;
- cout<<"Name:"<<Name<<endl;
- cout<<"Age:"<<Age<<endl;
- cout<<"Count:"<<count<<endl;
- show2();//在普通成员函数中调用静态成员函数
- }
- void Student::show2(){ //编译器不会为静态成员函数添加this指针
- cout<<"调用了方法show2"<<endl;
- 41 //cout<<"Name:"<<Name<<endl; //错误:静态成员函数不能访问非静态数据成员
- 42 //cout<<"Age:"<<Age<<endl; //错误:静态成员函数不能访问非静态数据成员
- 43 //show1(); //错误:静态成员函数中不能调用普通成员函数 (只能以this->show1()的形式调用)
- cout<<"Count:"<<count<<endl;
- }
- int main(){
- Student stu1("Tomwenxing",);
- Student stu2("Ellen",);
- Student stu3("Jack",);
- stu3.show1();
- cout<<"----------分界线----------------"<<endl;
- stu2.show2();//可以通过对象来调用静态成员函数
- cout<<"----------分界线----------------"<<endl;
- Student::show2() ;//也可以通过类来调用静态成员函数
- return ;
- }
C/C++:static用法总结的更多相关文章
- 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结
一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...
- 四种对象生存期和作用域、static 用法总结
一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...
- C语言中static用法介绍
C语言中static用法介绍 对于新手来说,很多东西的用法还不是很清楚,我们今天一起来看看C语言中static用法介绍 1.声明了static的变量称为静态变量,根据作用域的不同又分为 ...
- static用法总结
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 一.面向过程设计中的st ...
- c++ static用法总结【转载】
static关键字是C, C++中都存在的关键字.static从字面理解,是“静态的“的 意思,与此相对应的,应该是“动态的“. static的作用主要有以下3个: 1.扩展生存期: 2.限制作用域: ...
- (转-经典-数据段)C++回顾之static用法总结、对象的存储,作用域与生存期
转自:https://blog.csdn.net/ab198604/article/details/19158697相关知识补充:https://www.cnblogs.com/rednodel/p/ ...
- c/c++中static用法总结
static的作用主要有两种: 第一个作用是限定作用域:第二个作用是保持变量内容持久化: c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字static,全局变量就定义成一 ...
- 【C++初级】static用法总结、问题探讨及常见错误排查
static的基本用法: static的作用主要有两种第一个作用是限定作用域:第二个作用是保持变量内容持久化: 一.c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字sta ...
- java中静态代码块的用法 static用法详解和static静态导入
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- C/C++ static用法
这篇文章没有太多的实际内容,简单记录下static的用法.顺便试一下用markdown来写文章. 1. 在函数中使用 我们都知道在一个函数中的变量是存储在栈区中,函数的每一次调用都伴随着变量的重新定义 ...
随机推荐
- [图解tensorflow源码] Session::Run()流程图 (单机版)
- 网络编程中的read,write函数
关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Steve ...
- 06_Java基础语法_第6天(自定义类、ArrayList集合)_讲义
今日内容介绍 1.自定义类型的定义及使用 2.自定义类的内存图 3.ArrayList集合的基本功能 4.随机点名器案例及库存案例代码优化 01引用数据类型_类 * A: 数据类型 * a: java ...
- PHP切割字符用到的explode 以及计数count
在thinkphp中同样可以用 explode来进行字符的切割工作,比如 $jihe='1,2,3,4'; 在使用explode之后,可以获得一个数组: $array=explode(',',$jih ...
- Docker vs Warden
相同点: 都是依赖宿主操作系统内核的轻量级容器: 都采用了linux内核技术实现容器隔离(namespace)和资源限制(cgroup): 都使用了aufs文件系统: 不同点: 用途 warden是C ...
- An Introduction to the Basics of Modern CSS Buttons
https://www.sitepoint.com/modern-css-buttons/
- Openstack入门篇(十)之nova服务(计算节点)的部署与测试
1.安装服务软件包 [root@linux-node2 ~]# yum install -y centos-release-openstack-newton [root@linux-node2 ~]# ...
- iOS开发者证书-详解
iOS开发者证书-详解/生成/使用 本文假设你已经有一些基本的Xcode开发经验, 并注册了iOS开发者账号. 相关基础 加密算法 现代密码学中, 主要有两种加密算法: 对称密钥加密 和 公开密钥加密 ...
- REST API 开发
本文我们将使用Spring MVC 4实现 CRUD Restful WebService , 通过RestTemplate写一个 REST 客户端,定义这些服务. 我们也可以通过外部的一些客户端来测 ...
- Python面向对象之封装、property特性、绑定方法与非绑定方法
一.封装 ''' 1.什么封装 封:属性对外是隐藏的,但对内是开放的(对内是开放的是因为在类定义阶段这种隐藏已经发生改变) 装:申请一个名称空间,往里装入一系列名字/属性 2.为什么要封装 封装数据属 ...