IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 从浅入到深入了解static关键字 -> 正文阅读

[C++知识库]从浅入到深入了解static关键字

我们先来介绍下局部变量中static关键字的使用

局部变量:一般泛指方法里面声明的变量(一般局部变量不会自动初始化,静态局部变量自动初始化为0)
1.先来演示一下普通局部变量在程序中的变化过程

void run();//测试普通局部变量 
void run(){
	int i=1;
	printf("%d\n",i);
	i++;
	printf("%d\n",i);
}
int main(){
	printf("普通局部变量的结果\n"); 
	run();
	run();
}

结果
在这里插入图片描述

分析:当我们在函数中声明一下普通变量,我们可以理解它其实是存储在 进程栈空间,当函数调用结束后,里面的函数会被立即释放。

程序栈有啥

通常有局部变量,调用函数参数,被调函数返回地址,被调函数栈顶地址,函数返回值(返回值通常是由寄存器EAX返回的,因为速度较快)等。
在这里插入图片描述
程序栈介绍

2.接下来该演示静态局部变量在程序中的变化过程

void run2();//测试静态局部变量
void run2(){
	static int  j=1;
	printf("%d\n",j);
	j++;
	printf("%d\n",j);
}
int main(){
	printf("静态局部变量的结果\n"); 
	run2();
	run2();
}

结果
在这里插入图片描述

分析:在这里发现当第一次释放函数时,值并没有被释放出来,而是接着被第二个函数使用。这是为什么?原因是被static修饰的代码(不论是局部还是全局)都被放到了全局数据区生命周期很长(为一次程序的运行过程)并且只被初始化一次

3.有的同志又有问题了,C语言运行时内存到底是怎么划分的?

C语言运行时内存大致分为四个数据区:常量区、全局数据区(静态区)、堆区、栈区
在这里插入图片描述
常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 10,字符串常量”abcde”, 数组的名字等)
静态区(全局区):静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放
堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏
栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。
内存分区的详解介绍,引用大佬的

4.回归正题,学到这其实某些同学又有问题了,TM的我是闲的吗,我直接用全局变量来定义就是了,用什么static?好,这个疑问你先留着,看完下一个内容你就understand了

void run();//测试普通局部变量 
void run2();//测试静态局部变量
void run3();//不同函数声明同名的一个静态局部变量
void run(){
    int i=1;
	printf("%d\n",i);
	i++;
	printf("%d\n",i);
}
void run2(){
	static int  j=1;
	printf("%d\n",j);
	j++;
	printf("%d\n",j);	
}
void run3(){
	static int j=1; 
	printf("%d\n",j);
} 	
int main(){
	printf("普通局部变量的结果\n"); 
	run();
	run();
	printf("\n");
	printf("静态局部变量的结果\n"); 
	run2();
	run2();
	printf("再次调用局部静态变量\n"); 
	run3();//猜一下结果输出什么?
	
}

结果:
在这里插入图片描述
自己思考一下,给你一个小小的结论(如果不理解,继续看下面的演示)

静态变量的作用域其实是要看它所在的区域的,如果你在函数内部声明,O他的作用域就是这个函数,如果在外面声明,那作用域就是这个文件。

说完了局部那就再说一下全局的呗

全局变量:定义在函数外部的变量

问题来了,那全局变量和静态全局变量有啥区别?
我们先看看静态全局变量在多文件之间的调用过程

file.h

#include <stdio.h>
 
void printStr();
我们在file1.c中定义一个静态全局变量hello, 供file1.c中的函数printStr访问

#include "file1.h"
 
static char* hello = "hello cobing!";
 
void printStr()
{
	printf("%s\n", hello);
}
file2.c是我们的主程序所在文件,file2.c中如果引用hello会编译出错

#include "file1.h"
 
int main()
{
	printStr();
	printf("%s\n", hello);
	return 0;
}

结果: 报错hello未声明

如果我们将file2.c改为下面的形式:编译顺利通过

#include "file1.h"
int main()
{
	printStr();
	return 0;
}

结论:

静态全局变量,只在本文件可以用,虽然整个程序包含多个文件, 但静态全局变量只能用在定义它的那个文件里,却不能用在程序中的其他文件里。
普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了

最后一个问题,加static的函数

我想学了上述问题,应该运行结果很容易就猜到了。

file.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");
}

结果: 指定报错,原因对‘fun1’未定义的引用
在这里插入图片描述

改正:

file.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>

void fun1(void)
{
    printf("hello from static fun1.\n");
}

static函数与普通函数有什么区别?

static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。

总结:

其实static我们可以把他理解成Java中的private属性,只能供内部成员去访问,那平时做项目的时候有什么用呢?当做一个庞大的工程时,我们做某一模块的功能,我们可能让某些代码在这一个单独的模块内起作用,那我们就用到了static,出了这个模块,别人就不认识你了。

本文中章引用两位大佬的文章,并结合自己的理解来写了下面内容。如有侵权,联系立即删除。
https://blog.csdn.net/keyeagle/article/details/6708077
https://blog.csdn.net/guotianqing/article/details/79828100

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:14:26  更:2022-03-12 17:17:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:04:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码