C语言中static关键字用法

news2025/1/17 22:55:37

C语言中static关键字用法

2021年7月28日·席锦

static关键字在c语言中比较常用,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。但是对于c语言初学者,static由于使用灵活,并不容易掌握。

变量

1.局部变量

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

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。

实例程序:

#include <stdio.h>
 
int main(void)
{
    int a, b;
    static int c, d;
 
    _asm int 3        // 中断,在调试模式下查看a,b,c,d的值。可以看到a,b的值与c,d的值不同
 
    printf("%d, %d", c, d);        // 不加这一句无法在中断时查看到c,d的值。注意a,b未初始化不能使用
    return 0;
}

F5调试信息:

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

静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变;但是其作用域为局部作用域,当定义它的函数结束时,其作用域随之结束。

实例程序:

#include <stdio.h>
void fun(void)
{
    int n_1 = 10;
    printf("n=%d\n", n_1);
    n_1++;
    printf("n++=%d\n", n_1);
}
void fun_static(void)
{
    static int n_2 = 10;
    printf("static n=%d\n", n_2);
    n_2++;
    printf("n++=%d\n", n_2);
}
int main(void)
{
    // 普通局部变量,使用完毕会立即释放
    fun();
    printf("\n");
    fun();
 
    printf("--------------------\n");
 
    // 静态局部变量即使函数返回,它的值也会保持不变
    fun_static();
    printf("\n");
    fun_static();
 
    //printf("static n=%d\n", n_2);    // 打开本行语句编译就无法通过,因为变量n_2的作用域仅在fun_static()函数内
 
    return 0;
}

运行截图:

2.全局变量

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

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

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

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

实例程序:

/* demo.h */
#include <stdio.h>
 
/* demo.c */
#include "demo.h"
 
static int itest;        // 在demo2.c中也有一个一模一样的定义,但是程序编译运行正常
extern int itest2;        // 若是去掉extern将编译失败
 
int main(void)
{
    printf("hello world.\n");
 
    return 0;
}
 
/* demo2.c */
#include "demo.h"
 
static int itest;
int itest2;

运行截图:

函数

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

1)静态函数只能在声明或定义它的文件中可见,其他文件不能引用该函数

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

非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明

实例程序:

/* demo.h */
#include <stdio.h>
static void fun1(void);
static void fun2(void);
void callFun2(void);
 
/* demo.c */
#include "demo.h"
 
static void fun1(void)
{
    printf("hello from demo fun1.\n");
}
 
int main(void)
{
    fun1();    // 静态函数,定义在本文件中,可以直接调用
    //fun2();    // 打开注释,将无法编译通过。原因:函数fun2()是静态函数,且不在本文件中声明或定义
    callFun2();    // 非静态函数可以在另一个文件中直接引用
    return 0;
}
 
/* demo2.c */
#include "demo.h"
static void fun2(void)
{
    printf("hello from demo fun2.\n");
}
 
void callFun2(void)
{
    fun2();    // 静态函数,定义在本文件中,可以直接调用
}

运行截图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能手表上的音频(二):驱动

上一篇讲了智能手表上音频系统的架构和应用场景。从本篇开始讲具体的&#xff0c;首先讲音频相关的驱动&#xff0c;主要包括IPC&#xff08;inter-processor communication&#xff0c;核间通信&#xff0c; 即AP/CP/ADSP之间的通信&#xff09;的driver 和audio的driver。首先…

讯飞星火3.0版发布前瞻,生产力将大幅提升

AI头部企业科大讯飞宣布&#xff0c;即将在10月24日发布讯飞星火认知大模型3.0版。新版本将极大提升生产力&#xff0c;并开启大规模AI应用产业落地。 一、讯飞星火大模型3.0版即将升级发布 科大讯飞是AI人工智能技术、智能语音识别技术领域的全球领先企业&#xff0c;也是大…

垃圾回收器、垃圾回收算法、空间分配担保、JVM调优、GC回收对象的过程

文章目录 &#x1f34a; 垃圾回收器、垃圾回收算法、空间分配担保&#x1f389; Serial&#x1f389; ParNew&#x1f389; Parallel scavenge&#x1f389; 复制算法&#x1f389; 分代收集算法&#x1f389; 进入老年代的几种情况&#x1f4dd; 空间分配担保 &#x1f389; S…

PCI认证:为什么它对你的业务至关重要,以及如何成功获得认证?

PCI认证是保障你的业务安全和合规性的重要工具。它是一个由支付卡行业安全标准委员会(PCI SSC)提供的全球性标准&#xff0c;旨在保护持卡人信息和资金的安全。如果你的企业处理、存储或传输持卡人信息&#xff0c;那么PCI认证就对你的业务至关重要。 为什么PCI认证对你的业务至…

拼接屏新时代:了解OLED透明拼接屏的尺寸与定制选择

在当今科技迅速发展的时代&#xff0c;OLED透明拼接屏作为一项引人注目的创新技术&#xff0c;正在改变我们对于显示屏的认知。 它以其独特的透明性和高清晰度&#xff0c;为用户提供了前所未有的视觉体验。 一、OLED透明拼接屏原理 OLED&#xff08;Organic Light Emitting …

基于 Servlet 的博客系统

基于 Servlet 的博客系统 一、准备工作1、创建项目2、创建包3、导入前端静态页面 二、数据库设计1、blog&#xff08;博客表&#xff09;2、user&#xff08;用户表&#xff09;3、建库建表的 SQL 语句 三、封装数据库操作1、为什么要封装数据库&#xff1f;2、封装数据库的连接…

最高频的五个面试题

目录 1.JavaSE阶段&#xff1a;谈谈啥是多态 2.数据结构阶段&#xff1a;谈谈哈希表 3.数据库阶段&#xff1a;谈谈事务 4.操作系统阶段&#xff1a;谈谈进程和线程的区别联系 5.网络阶段&#xff1a;TCP三次握手和四次挥手 1.JavaSE阶段&#xff1a;谈谈啥是多态 多态&a…

解决方案-LBS用户位置Redis-GEO附近人/店铺

附近人 windows安装附近人列表功能mysqlredis GEO CNNVD-201511-230 未授权访问python 多线程 redis大端模式与小端模式IP地址的不同表现形式1.字符串表现形式2. 整数表现形式3.大小端模式下的IP地址 0x01 进入python正题Python的socket库1.socket.socket(family,type)2.socket…

【前端学习】—多种方式实现数组拍平(十一)

【前端学习】—多种方式实现数组拍平&#xff08;十一&#xff09; 一、数组拍平 数组拍平也叫数组扁平化、数组拉平、数组降维&#xff0c;指的是把多维数组转化为一维数组。 二、使用场景 复杂场景下的数据处理&#xff08;echarts做大屏数据展示&#xff09; 三、如何实…

华硕U盘盘重装Win10系统步骤图解

重装操作系统是在电脑系统遇到问题或者需要清除所有数据时的一种常见解决方法。但是&#xff0c;很多使用华硕电脑的新手用户&#xff0c;不清楚具体的操作步骤&#xff0c;接下来小编就给介绍关于利用U盘给华硕电脑重装Win10系统的方法&#xff0c;帮助用户们更快地完成系统的…

Shader Graph25-UV移动旋转缩放(自定义函数)

我们将UV操作放入函数内&#xff0c;该函数的内容来自我之前的文章 Shader Graph24-摇晃树叶-CSDN博客 一、UE在Material中右键&#xff0c;新建Material Function。 增加输入 二、新建Material&#xff0c;命名为DemoUVRotationUseFunction Offset为偏移值&#xff0c;Rotat…

VMware虚拟机安装Linux系统的介绍

许多新手连 Windows 的安装都不太熟悉&#xff0c;更别提 Linux 的安装了&#xff1b;即使安装成功了&#xff0c;也有可能破坏现有的 Windows 系统&#xff0c;比如导致硬盘数据丢失、Windows 无法开机等。所以一直以来&#xff0c;安装 Linux 系统都是初学者的噩梦。 然而&a…

填充颜色游戏

无语死了这题。 题目描述 小明最近迷上下面一款游戏。游戏开始时&#xff0c; 系统将随机生成一个 N N 的 正方形棋盘&#xff0c; 棋盘的每个格子都由六种颜色中的一种绘制。在每个步骤中&#xff0c; 玩家选择一种颜色&#xff0c; 并将与左上角连接的所有网格更改为该特…

MSQL系列(四) Mysql实战-索引 Explain实战

Mysql实战-索引 Explain实战 前面我们讲解了索引的存储结构&#xff0c;我们知道了BTree的索引结构&#xff0c;也了解了索引最左侧匹配原则&#xff0c;到底最左侧匹配原则在我们的项目中有什么用&#xff1f;或者说有什么影响&#xff1f;今天我们来实战操作一下&#xff0c…

Yakit工具篇:子域名收集的配置和使用

简介(来自官方文档) 子域名收集是指通过各种技术手段&#xff0c;收集某个主域名下所有的子域名列表。子域名是指在主域名前面添加一级或多级名称的域名。例如&#xff0c;对于主域名example.com&#xff0c;其子域名可以是www.example.com、mail.example.com、blog.example.c…

MIT6.5830 Lab0-Go tutorial实验记录(二)

MIT6.5830 Lab0-Go tutorial实验记录&#xff08;二&#xff09; – WhiteNights Site 标签&#xff1a;Golang, 数据库 在将数据库的数据转换为图表前&#xff0c;我们需要先测试是否能正常访问数据库文件。 写者注 为什么要怎么做&#xff1f;因为这块 非常容易出问题。在h…

计算机基础知识33

进程基础(操作系统中的概念) 进程它是操作系统总最重要的概念&#xff0c;线程也是 进程和线程都是有操作系统来调度使用的&#xff0c;我们程序员是不能控制的 # 进程和程序是两码事、完全不一样 程序&#xff1a;其实一个死的东西、一堆代码就是程序&#xff0c;它也没有生命…

【5】c++11新特性(稳定性和兼容性)—>override关键字

override关键字很简单&#xff0c;就是起到一个检查的作用&#xff0c;父类中有一个虚函数&#xff0c;子类要去重写这个虚函数&#xff0c;那么在子类重写时&#xff0c;函数后面加上override&#xff0c;就会检查子类中重写的这个函数和父类中这个虚函数名是否一样&#xff0…

FISCO过程中存在的的问题

问题1&#xff1a;端口被占 报错&#xff1a;Exceed waiting time. Please try again to start node0 initConfig for P2PInitializer failed,check Port30303,EINFOThrow location unknown (consider using BOOST_THROW_EXCEPTION) Dynamic exception type: boost::exception_…

80026-044-06-R 数字伺服驱动器提供了更好的配置和性能

80026-044-06-R 数字伺服驱动器提供了更好的配置和性能 由于它们的精密性能&#xff0c;伺服驱动器被用于机器人&#xff0c;自动化&#xff0c;数控加工&#xff0c;甚至在过程中制造半导体. 一些运动控制应用使用模拟伺服驱动器&#xff0c;这是一项久经考验的技术。虽然它…