前言: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用法总结的更多相关文章

  1. 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  2. 四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  3. C语言中static用法介绍

    C语言中static用法介绍     对于新手来说,很多东西的用法还不是很清楚,我们今天一起来看看C语言中static用法介绍     1.声明了static的变量称为静态变量,根据作用域的不同又分为 ...

  4. static用法总结

    C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 一.面向过程设计中的st ...

  5. c++ static用法总结【转载】

    static关键字是C, C++中都存在的关键字.static从字面理解,是“静态的“的 意思,与此相对应的,应该是“动态的“. static的作用主要有以下3个: 1.扩展生存期: 2.限制作用域: ...

  6. (转-经典-数据段)C++回顾之static用法总结、对象的存储,作用域与生存期

    转自:https://blog.csdn.net/ab198604/article/details/19158697相关知识补充:https://www.cnblogs.com/rednodel/p/ ...

  7. c/c++中static用法总结

    static的作用主要有两种: 第一个作用是限定作用域:第二个作用是保持变量内容持久化: c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字static,全局变量就定义成一 ...

  8. 【C++初级】static用法总结、问题探讨及常见错误排查

    static的基本用法: static的作用主要有两种第一个作用是限定作用域:第二个作用是保持变量内容持久化: 一.c语言中static的用法: 1.全局静态变量: 用法:在全局变量前加上关键字sta ...

  9. java中静态代码块的用法 static用法详解和static静态导入

    (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...

  10. C/C++ static用法

    这篇文章没有太多的实际内容,简单记录下static的用法.顺便试一下用markdown来写文章. 1. 在函数中使用 我们都知道在一个函数中的变量是存储在栈区中,函数的每一次调用都伴随着变量的重新定义 ...

随机推荐

  1. 解决yum安装 openssl-devel时产生的Multilib version problems found错误(转)

    Error: Multilib version problems found. This often means that the root cause is something else and m ...

  2. 通过ReentrantLock简单了解下并发包中的锁

    ReentrantLock在进行实例化时,可以通过构造函数的参数选择是否使用公平锁FairSync或者非公平锁NonfairSync,两者的区别比较简单,如果是公平锁则新来的线程会先检测同步队列中是否 ...

  3. 郑重推荐开源CANopen协议栈CANFestival(LGPL许可)!!!!!!!!

    郑重推荐开源CANopen协议栈CANFestival(LGPL许可)!!!!!!!!(这条文章已经被阅读了 次) 时间:2010/03/04 06:47am 来源:winshton [这个贴子最后由 ...

  4. vue watch关于对象内的属性监听

    vue可以通过watch监听data内数据的变化.通常写法是: data: { a: 100 }, watch: { a(newval, oldVal) { // 做点什么... console.lo ...

  5. #leetcode刷题之路39-组合总和

    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合.candidates 中的数字可以无限制重复被选取 ...

  6. CO借贷标识及转换

    前台提前数据源0CO_PC_01的数据时发现借贷方有O.C.S.D.不是传统的FI借贷标识(S = 借记,H = 贷记). 由"D"指出贷方记帐.从以下项中发生这些记帐 财务会计中 ...

  7. 说说MySQL索引

    前言 关于索引,这是一个非常重要的知识点,同样,在面试的时候也会被经常的问到: 本文描述了索引的结构,介绍了InnoDB的索引方案等知识点,感兴趣的可以看一下: 引入 本文参考文章:MySQL的索引 ...

  8. C语言的一道数组题Plus

    其实数组那部分当时学的东西挺简单的. 常见的题就是用一个数组装几个数字. 然后排序,找出大于n的数字有几个,有几个重复数字之类的. 去年想出来一个题. 因为以前写的代码太复杂,又有很多不足和bug.所 ...

  9. 在Visual Studio 2012中使用ASP.NET MVC5

    去年11月,.NET团队发布了用于 Visual Studio 2012 的 ASP.NET 和 Web 工具 2013.1 您可以从下面提供的链接下载该更新:  下载用于 Visual Studio ...

  10. P3674 小清新人渣的本愿

    P3674 小清新人渣的本愿 一道妙不可言的题啊,,, 一看就知道是个莫队 考虑求答案 1号操作就是个大bitset,动态维护当前的bitset \(S\),把能取哪些值都搞出来,只要\(S\ and ...