static in C/C++
最近经常碰到static,之前也使用过,但都是一知半解,所以下决心做个整理总结,搞搞灵清它到底用哪些作用。
一.static in C
1.默认初始化为0:
如果不显式地对静态变量进行初始化,它们将被初始化为0。
static变量存放在Global/Static(全局区/静态区)。在静态数据区,内存中所有的字节默认值都是0x00,所以在程序一开始时static声明的变量会被默认初始化为0。
2.static声明的变量会一直保持其值(局部静态对象)
static变量存放在Global/Static(全局区/静态区)。程序一开始,对其进行唯一一次初始化。被函数调用后,static变量不会消失,计算机会一直记录其值,其生命周期是贯穿函数调用及之后的时间。
#include <stdio.h>
void funcion(); int main()
{
for(int count = ; count <= ; count++) {
printf("第%d次调用:",count);
funcion();
} //for循环中的count内存被释放
return ;
} void funcion()
{
int temp = ;
static int count = ;//只在函数第一次调用时执行,后续函数调用此变量的初始值为上次调用后的值,每次调用后存储空间不释放
printf("temp = %d static count = %d\n",temp--, count--);
}
Eg Code
static count每次调用,其值减1,而temp每次都重新开始都为10。而主函数for循环中的count是在栈区的,作用域只在主函数的for循环中,当循环结束是存储空间自动释放。
3.具有内部链接的静态变量(static variable with internal linkage)
普通的外部变量可以被程序的任一文件所包含的函数使用,而具有内部链接的静态变量只可以被与它在同一个文件中的函数使用。
//举个例子
文件1:a.c
int money = ;
static wife = ;
int main()
{
money++;
printf("wife = %d\n",wife);
}
void function()
{
money--;
printf("wife = %d\n",wife);
}
文件2:b.c
int main()
{
extern int money;
money--;
printf("money = %d\n",money);
return ;
}
a.c中main函数,function函数皆可调用money和wife。b.c用外部声明extern money,是可以输出money = 9的。但是不能extern int wife,因为在a.c 中wife 加了static,其只允许在a.c中使用。(就像好兄弟money是可以共享的,但是wife不行!)
在多文件构成的程序中,如需共享一个外部变量,除了一个声明(定义声明)外,其他所有声明都要加extern;而如果不想被共享的变量,那就在声明时用static,表明该变量具有内部链接。
二.static in C++
1.静态数据成员
#include <iostream>
#include <string>
using namespace std; class Account
{
public:
static int sumAccount; //声明静态数据成员
void calculate() {
amount += amount * interestRate;
}
static double rate() {
return interestRate;
}
static double rate2(double interestRate2 = interestRate) {//使用静态成员作为默认实参。
return interestRate2;
}
// [Error] invalid use of non-static data member 'Account::amount'普通数据成员值不能作为默认实参
// static double showAmount(double Amount = amount) {
// return Amount;
// }
static void rate(double);
private:
string owner;
double amount;
static double interestRate; //声明静态数据成员
static double initRate();
};
double Account::interestRate = 0.30;//定义并初始化静态数据成员
int Account::sumAccount = ; //定义并初始化静态数据成员 int main()
{
Account ac1;
Account *ac2 = &ac1;
Account &ac3 = ac1;
cout << ac1.sumAccount << endl;
cout << ac2->sumAccount << endl;
cout << ac3.sumAccount << endl;
cout << Account::sumAccount << endl;
return ;
}
Eg Account Code
1.静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。静态数据成员只分配一次内存,即只存在一个static成员对象,被该类所有的对象共享。
Eg:每个Account对象都包含数据成员owner和amount。只存在一个interestRate对象被所有Account对象共享。
2.静态数据成员存放在Global/Static(全局区/静态区)。不是由类的构造函数初始化的。必须在类的外部定义和初始化每个静态数据成员,且只能定义一次。一旦被定义,就将存在于程序的整个生命周期。在外部定义静态数据成员时,不能重复static关键字。
Eg:静态数据成员的定义 double Account::interestRate = 0.30;
3.静态数据成员遵守public/protected/private访问规则。
4.静态数据成员的访问: (静态数据成员为public)
①作用域运算符直接访问静态数据成员
Eg: <类类型名>::<静态数据成员名>
Account::sumAccount;
②仍可以用类的对象,引用或者指针来访问静态数据成员。
Eg: <类对象名>.<静态数据成员名>
ac1.sumAccount;
5. 静态数据成员与普通成员区别:
①静态数据成员可以是不完全类型。指针成员可以是不完全类型。数据成员必须是完全类型。
②可以使用静态成员作为默认实参。普通数据成员值本身属于对象的一部分。(Eg:代码中被注释段)
③由于被该类所有的对象共享,改变其值,对于所有对象都改变了,无需逐一改变。
6. 静态数据成员与全局变量的区别:
①静态数据成员在类内,作用域与全局变量不同。且实现了封装性。
②静态数据成员可以实现信息隐藏,可以是private。而全局变量不能。
2.静态成员函数
#include <iostream>
#include <string>
using namespace std; class Account
{
public:
void calculate() {
amount += amount * interestRate;//非静态成员函数可以访问静态数据成员
}
static double rate() {
return interestRate; //静态成员之间可以相互访问
}
static void rate(double);
private:
string owner;
double amount;
static double interestRate;
static double initRate();
};
double Account::interestRate = 0.30; void Account::rate(double newRate) { //定义静态成员函数,不能重复static关键字
interestRate = newRate;
} int main()
{
Account ac1;
Account *ac2 = &ac1;
Account &ac3 = ac1;
cout << ac1.rate() << endl;
cout << ac2->rate() << endl;
cout << ac3.rate() << endl;
Account::rate(0.35);
cout << Account::rate() << endl;
return ;
}
Eg2 Account Code
1.静态成员函数不与任何对象绑定在一起,被所有Account对象共享。它们不包含this指针。静态成员函数不能声明称const的,且不能再static函数体内使用this指针。
2.静态成员函数,既可以定义在类内,也可以定义在类外部。(通常情况,类的静态成员应该在类的外部初始化。)在外部定义静态成员时,不能重复static关键字,只能出现在类的内部声明。
Eg:Eg2 Account Code 行23-25
3.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数
4.成员函数不用通过作用域运算符就直接使用静态函数。
5.静态成员函数的访问: (静态成员函数为public)
①作用域运算符直接访问静态成员函数
Eg: <类类型名>::<静态成员函数名>
Account::rate();
Account::rate(0.35);
②仍可以用类的对象,引用或者指针来访问静态成员函数。
Eg: <类对象名>.<静态成员函数名>
ac1.rate();
static in C/C++的更多相关文章
- static,你还敢用吗?(二)
为了压系统,昨天小组在测试环境模拟了一大批订单数据.今天上午查看记录的账单计息日志,发现了一大堆的MySqlException MySql.Data.MySqlClient.MySqlExceptio ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- PHP static静态属性和静态方法
这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...
- static,你还敢用吗?
我用火狐的HttpRequester测试开发组里一个同学发布的Web API接口,遇到了一个奇怪的问题. 我测试边界情况时,第一次调用响应的结果是正常的,但当再次及以后的请求时,却返回了异常“Syst ...
- Java关键字:static
通常,当创建类时,就是在描述那个类的外观和行为.只有用new创建类的对象时,才分配数据存储空间,方法才能被调用.但往往我们会有下面两种需求: 1.我想要这样一个存储空间:不管创建多少对象,无论是不创建 ...
- Android 中关于static的使用问题
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5251564.html 项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom ...
- iOS: 在UIViewController 中添加Static UITableView
如果你直接在 UIViewController 中加入一个 UITableView 并将其 Content 属性设置为 Static Cells,此时 Xcode 会报错: Static table ...
- 浅谈Static关键字
1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ...
- 今天思考一个问题,PHP const和static的区别
static关键字在类中是,描述一个成员是静态的,static能够限制外部的访问,因为static后的成员是属于类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心 ...
随机推荐
- Centos 时间同步服务器
From: http://www.iteye.com/topic/599648 中国国家授时中心: http://www.time.ac.cn/stime.asp 其他网络时间服务器地址如下:(也可以 ...
- jmeter随笔(29)-关于自己的jar包和beanshell的使用
点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...
- 慕课网-安卓工程师初养成-2-12 如何在Java中使用注释
来源:http://www.imooc.com/code/1274 在编写程序时,经常需要添加一些注释,用以描述某段代码的作用. 一般来说,对于一份规范的程序源代码而言,注释应该占到源代码的 1/3 ...
- 洛谷P1530 分数化小数 Fractions to Decimals
P1530 分数化小数 Fractions to Decimals 103通过 348提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交 讨论 题解 最新讨论 暂时没有讨论 题目 ...
- 洛谷P1466 集合 Subset Sums
P1466 集合 Subset Sums 162通过 308提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 对于从1到N (1 ...
- TCP/IP详解学习笔记(4)-- ARP 和 RARP
1.ARP 地址解析协议(Address Resolution Protocol,ARP)是在仅知道主机的IP地址时确地址解析协议定其物理地址的一种协议. 在TCP/IP协议中,A ...
- Spring 注解实体类中非数据库字段属性
解决办法:在属性的get方法上加上一段注解标识它是临时属性,不是数据库字段就OK @Transient public List<Reverts> getChildList() { retu ...
- win7和win8如何设置快速启动栏
a.在任务栏上右键 -> 工具栏 -> 新建工具栏 -> 跳出选择文件夹对话框,在文件夹里面(光标山洞处)输入这个路径,然后按回车: %userprofile%\AppData\Ro ...
- js获得浏览器的尺寸
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- HTTP协议概述
虽然cURL支持多种协议,但日常我们最常用的还是HTTP协议,下文中着重介绍HTTP的相关使用方法,因此我们要对HTTP协议有所了解. HTTP,超文本传送协议,通过因特网传送万维网文档的数据传送协议 ...