最近经常碰到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. VC++2005下的ADO SQL语句(like,count,distinct)和操作(转)

    http://blog.sina.com.cn/s/blog_56fd66a70100hxjf.html http://timke.blog.163.com/blog/#m=0 环境:MFC  Dia ...

  2. Android Activity 详述

    activity类处于android.app包中,继承关系: extends ContextThemeWrapper implements LayoutInflater.Factory2 Window ...

  3. Android开发-API指南-<instrumentation >

    <instrumentation> 英文原文:http://developer.android.com/guide/topics/manifest/instrumentation-elem ...

  4. infoWindowRenderer之个人见解

    在地图上以类似于提示框的方式显示查询信息,类似于arcmap中单击图层查看属性 由于Class Graphic有infoWindowRenderer : IFactory这个属性 (注:infoWin ...

  5. com学习(五)——实现多接口

    从第五回开始到第七回,咱们用 ATL 写了一个简单的 COM 组件,之所以说简单,是因为在组件中,只实现了一个自定义(custom)的接口 IFun.当然如果想偷懒的话,我们可以把 200 个函数都加 ...

  6. USACO Section 2.4 回家 Bessie Come Home

    题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛). 在挤奶 ...

  7. ASP.NET 数据库页面访问简单工具

    在工作中,有很多项目已上线后,很多项目的数据库服务器都不会对外开放的,外网想直接访问客户数据库服务器时,可能会出现困难. 这时就需要一个可以查询,更新数据库操作的页面了: 本来用sql语句直接操作数据 ...

  8. node.js 包教不包会 (Windows版详解)

    针对@alsotang 的新手入门教程 https://github.com/alsotang/node-lessons ,详解该教程在Windows中的实践,包括博主在实践过程中遇到的问题及解决方案 ...

  9. PAT1076. Forwards on Weibo(标准bfs模板)

    //标准的层次遍历模板 //居然因为一个j写成了i,debug半天.....解题前一定要把结构和逻辑想清楚,不能着急动手,理解清楚题意,把处理流程理清楚再动手,恍恍惚惚的写出来自己慢慢debug吧 # ...

  10. 安装Ecshop首页出现报错:Only variables should be passed by referen

    出现下面这就话: Strict Standards: Only variables should be passed by reference in E:\Tools\ECShop_V2.7.3_UT ...