C++中static关键字用法详解
概述
static关键字在c语言中比较常用,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。
但是对于c语言初学者,static由于使用灵活,并不容易掌握。本文就static在c语言中的应用进行总结,供参考使用。错漏之处,请不吝指正。
最后一节加入了c++面向对象中static的使用特性,当作拓展阅读。
变量
1. 局部变量
普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。
普通局部变量存储于进程栈空间,使用完毕会立即释放
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
变量在全局数据区分配内存空间;编译器自动对其初始化
其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束
小程序体会一下静态局部变量的威力:
#include<iostream>
using namespace std;void fun()
{int n = 10;cout << "n=" << n << endl;n++;cout << "n=" << n << endl;
}void fun_static(void)
{static int n = 10;cout << "n=" << n << endl;n++;cout << "n=" << n << endl;
}int main(void)
{cout << "第一次调用fun" << endl;fun();cout << "第二次调用fun" << endl;fun();cout << "第一次调用fun_static" << endl;fun_static();cout << "第二次调用fun_static" << endl;fun_static();system("pause");return 0;
}
运行结果如下:
第一次调用fun
n=10
n=11
第二次调用fun
n=10
n=11
第一次调用fun_static
n=10
n=11
第二次调用fun_static
n=11
n=12
可见,静态局部变量的效果跟全局变量有一拼,但是位于函数体内部,就极有利于程序的模块化了。
2. 全局变量
全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。
普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
test.cpp程序代码:
int golabel1 = 2;
(1)main.cpp程序代码如下时:
#include<iostream>
using namespace std;
int golabel1 = 1;
int main()
{cout << golabel1 << endl;system("pause");return 0;
}
此时编译器报错:
错误 2 error LNK1169: 找到一个或多个多重定义的符号
错误 1 error LNK2005: "int golabel1" (?golabel1@@3HA) 已经在 test.obj 中定义
(2)main.cpp程序代码如下时:
#include<iostream>
using namespace std;
extern int golabel1;
int main()
{cout << golabel1 << endl;system("pause");return 0;
}
此时输出结果为:
2
(3)main.cpp程序代码如下时:
#include<iostream>
using namespace std;
static int golabel1 = 1;
int main()
{cout << golabel1 << endl;system("pause");return 0;
}
此时输出结果为:
1
静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。
在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用
函数
函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:
- 静态函数只能在声明它的文件中可见,其他文件不能引用该函数
- 不同的文件可以使用相同名字的静态函数,互不影响
非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明
面向对象
静态数据成员
在类内数据成员的声明前加上static关键字,该数据成员就是类内的静态数据成员。其特点如下:
- 静态数据成员存储在全局数据区,静态数据成员在定义时分配存储空间,所以不能在类声明中定义
- 静态数据成员是类的成员,无论定义了多少个类的对象,静态数据成员的拷贝只有一个,且对该类的所有对象可见。也就是说任一对象都可以对静态数据成员进行操作。而对于非静态数据成员,每个对象都有自己的一份拷贝。
- 由于上面的原因,静态数据成员不属于任何对象,在没有类的实例时其作用域就可见,在没有任何对象时,就可以进行操作
- 和普通数据成员一样,静态数据成员也遵从public, protected, private访问规则
- 静态数据成员的初始化格式:<数据类型><类名>::<静态数据成员名>=<值>
- 类的静态数据成员有两种访问方式:<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
同全局变量相比,使用静态数据成员有两个优势:
- 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性
- 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能
静态成员函数
与静态数据成员类似,静态成员函数属于整个类,而不是某一个对象,其特性如下:
- 静态成员函数没有this指针,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数
- 出现在类体外的函数定义不能指定关键字static
- 非静态成员函数可以任意地访问静态成员函数和静态数据成员
总结
static是一个很有用的关键字,使用得当可以使程序锦上添花。当然,有的公司编码规范明确规定只用于本文件的函数要全部使用static关键字声明,这是一个良好的编码风格。
无论如何,要在实际编码时注意自己的编码习惯,尽量体现出语言本身的优雅和编码者的编码素质。
C++中static关键字用法详解相关推荐
- C++中const关键字用法详解及实例和源码下载(一)
最近在学习C++基础部分,看了两天书,已经看过了一遍,半知半解,回过头来重新看第二遍,深入了解一下C++的基础知识.现在读到了const关键字的用法,书上面讲解的时候并没有给出完整的实例,只是理论的讲 ...
- c++中static的用法详解
C 语言的 static 关键字有三种(具体来说是两种)用途: 1. 静态局部变量:用于函数体内部修饰变量,这种变量的生存期长于该函数. 下面展示一些 内联代码片. int foo(){static ...
- c语言中static关键字用法详解
概述 static关键字在c语言中比较常用,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护. 但是对于c语言初学者,static由于使用灵活,并不容易掌握.本文就static在c语言中的应用进 ...
- python中的super用法详解_【Python】【类】super用法详解
一.问题的发现与提出 在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1: 代码段1: class A: def __init__(sel ...
- java中throws用法_java中throws实例用法详解
在程序出现异常时,会有一个抛出异常的throw出现,这里我们要跟今天所讲的throws区分开.throws的作用是声明抛出,在名称上也跟throw有所不同.下面我们就throws对策概念.语法.实例带 ...
- STL 中map的用法详解
STL 中map的用法详解 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可 ...
- mysql常见关键字的用法_MySQL 常用关键字用法详解
MySQL 常用关键字用法详解 在开发工程中,操作数据库的时候经常会有不同类型的条件查询,除了使用where外,Mysql本身也提供了很多常用的关键字.本文主要介绍一些常用的关键字,像update.i ...
- C++中substr()函数用法详解
C++中substr()函数用法详解 原型: string substr (size_t pos = 0, size_t len = npos) const; 返回一个新构造的string对象,其值初 ...
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
- C#中NameValueCollection类用法详解
C#中NameValueCollection类用法详解,1.NameValueCollection类集合是基于 NameObjectCollectionBase 类. 但与 NameObjectCol ...
最新文章
- python使用TSNE为影像组学(radiomics)数据进行降维可视化分析
- 圣杯布局与双飞翼布局全解
- JavaScript中this的五种绑定方式详解
- lucene索引合并与增量索引
- 多个线程同时运行,顺序打印问题
- [转].Net实现本地化简易教程
- 利益相关者软件工程_如何向利益相关者解释用户体验的重要性
- 【数据结构学习之完全从零实现所有数据结构的代码编写之二】智能指针
- log4j和logback的冲突导致日志输出异常
- androidq获取文件正式路径_android Q 新特性
- Deploy Office Communications Server 2007R2 Group Chat Server(一)
- eclipse没有Web分支Dynamic Web Project
- 11年写的一篇文章----智能终端安全现状及前景展望
- android - startActivity浅谈
- Mysql内连接和外连接的区别
- eclipse Git使用教程
- 日系IP的五大“坑”
- 沈师 PTA 数据库题目及部分解析 第十章
- imToken 投资 imKey 并推出通用硬件钱包方案
- 脉冲多普勒雷达设计附matlab代码
热门文章
- 循环队列的创建Java_Java版-数据结构-队列(循环队列)
- vue mysql交互_几种vue的数据交互形式
- java+log4j+是异步吗_log4j2用asyncRoot配置异步日志是如何使用disruptor
- 为什么 Flink 无法实时写入 MySQL?
- MAC环境配置SDK
- 字节跳动一面:如何从 100 亿 URL 中找出相同的 URL?
- 3d游戏计算机硬件配置方案,做三维如何配电脑?内容创作者配置推荐
- python选取tensor某一维_Python按维数操作多维张量,Pytorch,对,Tensor,维度
- zepto怎么设置宽高_【五个阿道夫】剧本杀测评 | 娱乐流量当道的时代 这个世界怎么了...
- mysql 创建外键语句,MySQL 创建主键,外键和复合主键的语句 | 很文博客