最近经常碰到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

//class Account -->银行账户

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++的更多相关文章

  1. static,你还敢用吗?(二)

    为了压系统,昨天小组在测试环境模拟了一大批订单数据.今天上午查看记录的账单计息日志,发现了一大堆的MySqlException MySql.Data.MySqlClient.MySqlExceptio ...

  2. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  3. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  4. PHP static静态属性和静态方法

    这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...

  5. static,你还敢用吗?

    我用火狐的HttpRequester测试开发组里一个同学发布的Web API接口,遇到了一个奇怪的问题. 我测试边界情况时,第一次调用响应的结果是正常的,但当再次及以后的请求时,却返回了异常“Syst ...

  6. Java关键字:static

    通常,当创建类时,就是在描述那个类的外观和行为.只有用new创建类的对象时,才分配数据存储空间,方法才能被调用.但往往我们会有下面两种需求: 1.我想要这样一个存储空间:不管创建多少对象,无论是不创建 ...

  7. Android 中关于static的使用问题

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5251564.html 项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom ...

  8. iOS: 在UIViewController 中添加Static UITableView

    如果你直接在 UIViewController 中加入一个 UITableView 并将其 Content 属性设置为 Static Cells,此时 Xcode 会报错: Static table ...

  9. 浅谈Static关键字

    1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ...

  10. 今天思考一个问题,PHP const和static的区别

    static关键字在类中是,描述一个成员是静态的,static能够限制外部的访问,因为static后的成员是属于类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心 ...

随机推荐

  1. JQuery上传插件uploadify整理(Options)

    下载  现在有两个版本了,我此次使用的依然是Flash版本的,虽然现在绝大部分浏览器都兼容HTMKL5,目前位置,除了做手机项目外,一般我们项目中不允许使用HTML5标签. 属性介绍(Options) ...

  2. iOS 7.0获取iphone UDID 【转】

    iOS 7.0 iOS 7中苹果再一次无情的封杀mac地址,使用之前的方法获取到的mac地址全部都变成了02:00:00:00:00:00.有问题总的解决啊,于是四处查资料,终于有了思路是否可以使用K ...

  3. 制作chm无搜索标签解决方法

    chm无搜索标签解决方法: 1.hpp文件中设置Full-text search=Yes 2.下面[windows]有个数字设置为0x420, 网上普通流传的是0x20 === chm制作一般要三个文 ...

  4. Jmeter命令行方式启动

    在性能测试过程中,我们常常遇到这样的问题,使用Jmeter的GUI界面进行大并发量的性能测试时,界面容易卡死,无法继续进行性能测试.通过使用命令行方式启动jmeter是一个不错的方式.下面就简单介绍一 ...

  5. 置换贴图 Displacement Mapping

    视差贴图和法线贴图都是使用特定的手段来达到欺骗视觉的目的,让人以为物体的表面是凹凸起伏的.而置换贴图却是真的将模型的顶点进行偏移,在原本的平面上创造出凹凸的效果.既然是对顶点进行偏移,那么就需要模型有 ...

  6. 多XML追加操作

    假设要统计当前系统中所有的试卷进行分析,试卷是以XML格式存储的,所有这就需要将所有零散的XML文件整合起来,处理成一个完整的XML文件,进行分析, 下面是简单额处理方法: 当前XML文件格式: &l ...

  7. 【Struts 1】Struts1的基本原理和简介

    备注:这里介绍的是Struts1的内容,Struts2的内容,会在后续的博客的予以说明! 一.什么是Struts struts的目标是提供一个开发web应用的开源框架,Struts鼓励基于Model2 ...

  8. ajax contenttype

    jquery ajax基本形式: $.ajax({ type: 'POST/get', url: '', data: {"n":n,"m":m}, dataTy ...

  9. Oracle删除用户和表空间

    对于单个user和tablespace 来说, 可以使用如下命令来完成. 步骤一:  删除user drop user ×× cascade 说明: 删除了user,只是删除了该user下的schem ...

  10. 【MySQl】MyISAM和InnoDB索引对比

    部分内容转自:http://www.2cto.com/database/201211/172380.html 比较好的文章:http://www.cnblogs.com/hustcat/archive ...