在程序中使用static

变量

1. 局部变量

普通局部变量是再熟悉不过的变量了,在任何一个函数内部定义的变量(不加static修饰符)都属于这个范畴。编译器一般不对普通局部变量进行初始化,也就是说它的值在初始时是不确定的,除非对其显式赋值。

普通局部变量存储于进程栈空间,使用完毕会立即释放。

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

变量在全局数据区分配内存空间;编译器自动对其初始化

其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束

小程序体会一下静态局部变量的威力:

#include <stdio.h>

void fn(void)
{
int n = 10; printf("n=%d\n", n);
n++;
printf("n++=%d\n", n);
} void fn_static(void)
{
static int n = 10; printf("static n=%d\n", n);
n++;
printf("n++=%d\n", n);
} int main(void)
{
fn();
printf("--------------------\n");
fn_static();
printf("--------------------\n");
fn();
printf("--------------------\n");
fn_static(); return 0;
}

运行结果:

-> % ./a.out
n=10
n++=11
--------------------
static n=10
n++=11
--------------------
n=10
n++=11
--------------------
static n=11
n++=12

2. 全局变量

全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。

普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。

静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。

在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。

3.函数

函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:

  • 静态函数只能在声明它的文件中可见,其他文件不能引用该函数

  • 不同的文件可以使用相同名字的静态函数,互不影响

  • 非静态函数可以在另一个文件中直接引用

下面两个文件的例子说明使用static声明的函数不能被另一个文件引用:

/* file1.c */
#include <stdio.h> static void fun(void)
{
printf("hello from fun.\n");
} int main(void)
{
fun();
fun1(); return 0;
} /* file2.c */
#include <stdio.h> static void fun1(void)
{
printf("hello from static fun1.\n");
}

使用gcc file1.c file2.c编译时,错误报告如下:

/tmp/cc2VMzGR.o:在函数‘main’中:
static_fun.c:(.text+0x20):对‘fun1’未定义的引用
collect2: error: ld returned 1 exit status

修改文件,不使用static修饰符,可在另一文件中引用该函数:

/* file1.c */
#include <stdio.h> void fun(void)
{
printf("hello from fun.\n");
} /* file2.c */
int main(void)
{
fun(); return 0;
}

同样使用gcc file1.c file2.c编译,编译通过,运行结果如下:

-> % ./a.out
hello from fun.

4.面向对象

静态数据成员

在类内数据成员的声明前加上static关键字,该数据成员就是类内的静态数据成员。其特点如下:

  • 静态数据成员存储在全局数据区,静态数据成员在定义时分配存储空间,所以不能在类声明中定义

  • 静态数据成员是类的成员,无论定义了多少个类的对象,静态数据成员的拷贝只有一个,且对该类的所有对象可见。也就是说任一对象都可以对静态数据成员进行操作。而对于非静态数据成员,每个对象都有自己的一份拷贝。

  • 由于上面的原因,静态数据成员不属于任何对象,在没有类的实例时其作用域就可见,在没有任何对象时,就可以进行操作。

  • 和普通数据成员一样,静态数据成员也遵从public, protected, private访问规则

  • 静态数据成员的初始化格式:<数据类型><类名>::<静态数据成员名>=<值>

  • 类的静态数据成员有两种访问方式:<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

同全局变量相比,使用静态数据成员有两个优势:

  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。

  • 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能

5.静态成员函数

与静态数据成员类似,静态成员函数属于整个类,而不是某一个对象,其特性如下:

  • 静态成员函数没有this指针,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。

  • 出现在类体外的函数定义不能指定关键字static。

  • 非静态成员函数可以任意地访问静态成员函数和静态数据成员。

Static关键词的更多相关文章

  1. C和指针 第三章 变量的储存类型 auto、static、register以及static关键词

    变量的储存类型决定标量何时创建,何时销毁以及他的值保持多久.有三个地方可以储存变量: 普通内存static 运行时堆栈auto 硬件寄存器register 变量的缺省储存类型取决于它的声明位置: 静态 ...

  2. java中的static关键词

    以下来自:http://www.cnblogs.com/codc-5117/archive/2011/12/04/2275298.html Static基本规则:             (1)一个类 ...

  3. 作用域的一些说明,static关键词

    作用域的一些说明 变量分为全局变量和局部变量.学过C语言的童鞋都知道,全局变量的作用域是整个整个文件.在即使在函数内部也有效,但在php中,如果在函数中使用全局变量,php会认为这个变量没有定义.如果 ...

  4. Java学习(final、static关键词)

    final关键词 概念:final的意思为最终,不可变.final是个修饰符,它可以用来修饰类,类的成员,以及局部变量.不能修饰构造方法. 特点: 1.final修饰的类不可以被继承,但可以继承别的类 ...

  5. java基础(五)之static关键词的作用

    static关键词的作用 1.静态成员变量的语法特定2.静态函数的语法特定3.静态代码块的语法特定 定义静态成员变量 Person.java class Person{ static int a; } ...

  6. C# Static关键词的使用

    一.C#中类的方法分为静态方法和非静态方法 静态方法有Static关键词修饰 静态方法归类所有,而非静态方法归类的实例所有:静态方法无需类去实例化可直接调用 静态成员属于类所有,为各个类的实例所公用, ...

  7. 链接(extern、static关键词\头文件\静态库\共享库)

    原文链接:http://www.orlion.ga/781/ 一. 多目标文件的链接 假设有两个文件:stack.c: /* stack.c */ char stack[512]; int top = ...

  8. C/C++中static关键词的作用

    1.在函数体内的static变量作用范围是该函数体,其只被内存分配一次,所以在下次调用的时候会保持上一次的值. 2.模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外的函数访问. ...

  9. 第一章 02 谈谈static关键词

    引文一下吧 http://blog.csdn.net/hackbuteer1/article/details/7487694 一.static在C语言中的含义 1.静态变量作用范围在一个文件内,程序开 ...

  10. ava下static关键字用法详解

    Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static ...

随机推荐

  1. PostgreSql: 安装与链接

    环境介绍 使用宝塔面板,在阿里云中安装PostgreSql,并使用DataGrip在本地进行链接 postgresql 配置 安装postgresql 在宝塔中安装postgresql 管理器 在此处 ...

  2. PyQt5实时刷新

    对于执行很耗时的程序来说,由于PyQt需要等待程序执行完毕才能进行下一步,这个过程表现在界面上就是卡顿,而如果需要执行这个耗时程序时不断的刷新界面.那么就可以使用QApplication.proces ...

  3. Mysql 统计标签出现次数(一行变多行)

    需求背景 需求 一张数据表 其中有sid字段,代表tag,每行数据可能有多个tag字段 统计全量数据中所有tag出现的次数(按tag分组,分别有多少数据) source table demo id s ...

  4. 痞子衡嵌入式:借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是借助i.MXRT10xx系列INIT_VTOR功能可以缩短程序热重启时间. 最近痞子衡写了篇文章 <i.MXRT从Serial N ...

  5. Flutter系列文章-Flutter UI进阶

    在本篇文章中,我们将深入学习 Flutter UI 的进阶技巧,涵盖了布局原理.动画实现.自定义绘图和效果.以及 Material 和 Cupertino 组件库的使用.通过实例演示,你将更加了解如何 ...

  6. 最常用的Linux命令

    1. tar 创建一个新的tar文件 $ tar cvf archive_name.tar dirname/ 解压tar文件 $ tar xvf archive_name.tar 查看tar文件 $ ...

  7. Ubuntu 安装部署Kubernetes(k8s)集群

    目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.配置节点的基本环境 五.节点安装doc ...

  8. 文心一言 VS 讯飞星火 VS chatgpt (77)-- 算法导论7.3 2题

    二.如果用go语言,在 RANDOMIZED-QUICKSORT 的运行过程中,在最坏情况下,随机数生成器 RANDOM 被调用了多少次?在最好情况下呢?以θ符号的形式给出你的答案? 文心一言: 在 ...

  9. AI绘画StableDiffusion实操教程:冰霜旗袍美女

    飞书原文链接,获取更多资源:AI绘画StableDiffusion实操教程:冰霜旗袍美女 前几天分享了StableDiffusion的入门到精通教程:AI绘画:Stable Diffusion 终极炼 ...

  10. API接口的研发与应用

    ​ API(Application Programming Interface,应用程序编程接口)指的是为不同的软件应用程序提供编程接口的一组协议.规则以及工具的集合,以便它们能够互相交互,实现数据通 ...