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. 在函数中使用 我们都知道在一个函数中的变量是存储在栈区中,函数的每一次调用都伴随着变量的重新定义 ...
随机推荐
- windows内核Api的学习
windows内核api就是ntoskrnl.exe导出的函数.我们能够跟调用应用层的api一样,调用内核api. 只是内核api须要注意的是.假设函数导出了.而且函数文档化(也就是能够直接在msdn ...
- iview 或 element-ui table 列表表头加样式
table 表头有时候需要加一些小样式比如 必填项 这是我项目中遇到的需求=== 比例,产品, 部门为必填项,这个时候就需要在表头加个红色小星星. 首先在table中绑定:header-cell-c ...
- 基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块
基于 HTML5 Canvas 的智能安防 SCADA 巡逻模块 前言 最近学习了 HT for Web flow 插件,除了正常的 flow 效果,其中还有两个十分好用的两个接口 getPercen ...
- PHPCMS v9 手机端栏目绑定模板
phpcms的手机端,模块是有了,但是有些地方用的还不是很舒服,其中移动端栏目无法绑定模板就不是很方便.如图,所有的栏目绑定的模板是固定的. 这次咱们就来处理下,移动端如何设置相应的模板.这里说是设置 ...
- Scala_标识符
用于对象,类,变量和方法的名称称为标识符.关键字不能用作标识符,标识符区分大小写. 类名首字母大写 方法名称第一个字母小写 程序文件名应该与对象名称完全匹配 1.字母数字标识符 以字母或下划线开头,后 ...
- 用NI的数据采集卡实现简单电子测试之6——数字I/O及测试平台
本文从本人的163博客搬迁至此. 前面几个例子介绍了NI数据采集卡的模拟输入和输出功能,本例则集中介绍USB-6009的数字输入输出功能.本例包括基本数字IO电路及在LabVIEW中控制USB-600 ...
- 查内存命令之free
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页 回到顶级页面:PostgreSQL索引页 [作者 高健@博客园 luckyjackgao@gmail. ...
- mfc 类
知识点 类的概念 类的相关术语 定义类 使用类 一.类的概念 简单的说类就是数据与函数综合体,它是用户自定义类型. 二.类的相关术语 类的实例称为对象. 类在定义中隐式地包含数据和操作函数,这种思想称 ...
- 洛谷 P1306 斐波那契公约数
洛谷 P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? ...
- 洛咕P3250 [HNOI2016]网络 整体二分
这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...