由浅到深认识C语言(6):变量的存储类型

news2024/11/19 2:36:39

该文章Github地址:https://github.com/AntonyCheng/c-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识C语言(5):函数

5.变量的存储类别

5.1.内存的分区

可执行文件未运行时所占内存:

bss段:全局未初始化数据

data段:全局初始化数据

text段:代码段

可执行文件运行时所占内存:

堆区:使用malloc , calloc , realloc , free动态申请和释放

栈区:局部变量/数组、函数形参以及函数中大于 4B 的返回值

全局区:全局未初始化数据,全局初始化数据,全局变量和静态变量static bss段和data段)

文字常量区:字符串常量、符号常量

代码区:代码段,二进制代码text段)

各个区域的读写性:

可读可写:堆区、栈区、全局区;

只读:文字常量区、代码区;

5.2.变量类型

普通局部变量

定义形式:在 {} (复合语句)里面定义的普通变量;

void test()
{//复合语句
    int num = 0; //普通变量
}

作用范围:离它最近的大括号之间有效;

void test()
{//复合语句
    int num1 = 0; //普通局部变量 num1 对外层大括号有效
    {
        int num2 = 0; //普通局部变量 num2 对内层大括号有效
    }
    printf("num2 = %d",num2); //这里会报错,找不到 num2 这一个变量
}

生命周期:离它最近的大括号有效,离开大括号的局部变量,系统自动回收;

存储区域:栈区;

注意事项

  1. 普通局部变量不初始化,内容不确定;

  2. 普通局部变量如果同名且不报错的情况下,就近原则;

    void test(){
        int data = 100;
        {
            int data = 200;
            printf("A = %d",data); //这里 A = 200
        }
        printf("B = %d",data); //这里 B = 100
    }
    

    但是我们要杜绝同名的情况;

普通全局变量

定义形式:定义在函数外边的变量,称之为全局变量;

int data; //这里就是普通全局变量
void test(){
    
}
int main(int argc,char *argv){
    
}

作用范围:当前的源文件都有效(可加可不加 extern),如果让这个变量在其他源文件有效的话,必须加上 extern;

#include<stdio.h>
extern int num; //由于 num 在调取函数之间,所以此处要像函数一样声明一下;
//上面的这个代码尽量加一个 extern ,保证代码的可读性;
void test01() {
	printf("test01 中 num = %d\n", num);
}
int num = 100; //这里就是 num 的一个全局变量;
void test02() {
	printf("test02 中 num = %d\n", num);
}
int main(int argc, char* argv[]){
	printf("main 中 num = %d\n", num);
	test01();
	test02();
	return 0;
}
//打印结果都为 num = 100;

生命周期:整个进程都有效,程序结束的时候,全局变量才被释放;

存储区域:全局区;

注意事项

  1. 全局变量不初始化,内容为零,原因是不初始化的话就会被放在bss段,该段会自动置零;

  2. 如果全局变量要在其他源文件中使用,必须在所使用的源文件中加 extern 声明;

  3. 如果全局变量和局部变量同名,在大括号语句中优先使用局部变量;

    int num = 100;
    int main(int argc,char *argv){
        num = 10;
        printf("num = %d",num);//这里打印出来是 num = 10
    }
    

静态局部变量

定义形式:在大括号中定义,前面必须加 static 修饰,这样的变量叫静态全局变量;

#include<stdio.h>
void test() {
	static int num;//静态局部变量;
	return;
}
int main(int argc, char *argv[]) {
	test();
	return 0;
}

作用范围:离它最近的大括号之间有效;

#include<stdio.h>
void test() {
	{
		static int num;//静态局部变量;
	}
	printf("num = %d\n", num);//这里不识别 num
	return;
}
int main(int argc, char *argv[]) {
	test();
	return 0;
}

生命周期:整个进程,程序结束的时候静态局部变量才被释放;

我们来比较一下普通局部变量和静态局部变量:

普通局部变量:

#include<stdio.h>
void test() {
	int num = 10;
	num++;
	printf(" %d ", num);
	return;
}
int main(int argc, char *argv[]) {
	test();
	test();
	test();
	test();
	printf("\n");
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

静态局部量:

#include<stdio.h>
void test() {
	static int num = 10;
	num++;
	printf(" %d ", num);
	return;
}
int main(int argc, char *argv[]) {
	test();
	test();
	test();
	test();
	printf("\n");
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

存储区域:全局区;

注意事项

  1. 静态局部变量如果不初始化,内容为零;
  2. 只能被定义一次(重要);

静态全局变量

定义形式:在函数外边定义,同时加上 static 修饰;

#include<stdio.h>
static data = 10;//静态全局变量
void test() {
	return;
}
int main(int argc, char *argv[]) {
	return 0;
}

作用范围:当前源文件有效,不能在其他源文件使用;

生命周期:整个进程,当程序结束后,静态全局变量才会被识别

存储区域:全局区;

注意事项

  1. 静态全局变量不初始化,内容为零;
  2. 静态全局变量只在当前源文件有效;

5.3.函数类型

全局函数(普通函数)

void test() {
	printf("这就是一个全局函数\n");
	return;
}
  • **特点:**其他源文件可以使用全局函数,但是必须加 extern 声明;

静态函数(局部函数)

static void test() {
	printf("这就是一个静态函数\n");
	return;
}
  • **特点:**其他源文件不可以直接使用静态函数,只能在当前源文件使用;
  • **注意:**如果想在其他源文件直接调用静态函数,需要将静态函数封装在全局函数中,同时全局函数和静态函数必须是同一个源文件,这样可以在其他源文件中直接调用全局函数,然后由全局函数直接调用静态函数;

**案例:**计算;

  • fun1.c

    int va = 7;
    int getG(void){
        int va = 20;
        return va;
    }
    // va = 7(是); getG = 20;(是)
    
  • fun2.c

    static int va = 18;
    static int getG(void){
    	return va;
    }
    int getO(void){
        return getG();
    }
    // va = 18(否); getG = 18(否); getO = 18(是);
    
  • main.c

    #include<stdio.h>
    extern int va;
    extern int getG(void);
    extern int getO(void);
    int main(void){
        printf("va = %d\n",va);				//答案为 7
        printf("getO = %d\n",getO());		//答案为 18
        printf("getG = %d\n",getG());		//答案为 20
        printf("%d\n",va*getO()*getG());	//答案为 2520
    }
    

下一章:由浅到深认识C语言(7):预处理&二进制

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

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

相关文章

代码随想录算法训练营第40天 | 343. 整数拆分 ,96.不同的二叉搜索树

动态规划章节理论基础&#xff1a; https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 343. 整数拆分 题目链接&#xff1a;https://leetcode.cn/problems/integer-break/ 思路&#xff1a; 动规五部曲&#xf…

【复现】通天星CMS 安全监控云平台 SQL注入漏洞_64

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 通天星CMSV6拥有以位置服务、无线3G/4G视频传输、云存储服务为核心的研发团队&#xff0c;专注于为定位、无线视频终端产品提供平…

sqllab第三关通关笔记

知识点&#xff1a; 通过回显的信息判断原始语句的组成猜测该语句为 select 1,2,3 from 表名 where id (输入) limit 0,1 首先通过测试判断存在什么类型的sql注入 构造id1/0 发现正常输出&#xff1b;说明是字符型的sql注入 好了&#xff0c;下面就测试有什么限制条件 构造…

论文阅读——MoCo

Momentum Contrast for Unsupervised Visual Representation Learning 动量在数学上理解为加权移动平均&#xff1a; yt-1是上一时刻输出&#xff0c;xt是当前时刻输入&#xff0c;m是动量&#xff0c;不想让当前时刻输出只依赖于当前时刻的输入&#xff0c;m很大时&#xff0…

使用Laravel开发项目

如何使用Laravel框架开发项目 一、安装Laravel框架 1.在安装Laravel框架钱我们需要先查看要安装的Laravel框架版本以及版本所需要的安装运行条件。 2.配置好安装环境后再安装Laravel框架 2.1.配置安装环境 1&#xff09;PHP版本 2&#xff09;PHP OpenSSL扩展 3&#xff…

Ubuntu查看ros版本-linux查看ros版本

使用ros带的rosversion命令即可查看自己的ros版本&#xff1a; rosversion -d

C语言葵花宝典之——文件操作

前言&#xff1a; 在之前的学习中&#xff0c;我们所写的C语言程序总是在运行结束之后&#xff0c;就会自动销毁&#xff0c;那如果我们想将一个结果进行长期存储应该如何操作呢&#xff1f;这时候就需要我们用文件来操作。 目录 1、什么是文件&#xff1f; 1.1 程序文件 1.2…

C语言 之 结构体超详细总结

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文(平均质量分78.8)&#xff0c;分…

docker容器镜像管理

目录 一、 Docker的基本组成 二、 容器和镜像的关系 2.1 面向对象角度 2.2 从镜像容器角度 三、镜像命令 3.1 查看当前已有镜像 3.2 查看已有的全部镜像 3.3 查看镜像ID 3.4 镜像删除 四、 容器命令 4.1 下载镜像 4.2 新建和启动容器 run 4.3 交互式 4.…

【体验有奖】用 AI 画春天,函数计算搭建 Stable Diffusion WebUI

人工智能生成内容 AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;是当下备受关注的概念之一&#xff0c;是继 PGC 和 UGC 之后的新型生产方式。AIGC 技术的核心思想是利用人工智能算法生成具有一定创意和质量的内容。例如&#xff0c;根据用户的描述或…

字符分类函数(iscntrl、i是space.....)---c语言

目录 一、定义二、字符分类函数2.1 -iscntrl&#xff08;&#xff09;2.1.1定义2.1.2使用举例 2.2 -isspace&#xff08;&#xff09;2.2.1描述2.2.2使用举例 2.3-isdigit()2.3.1描述2.3.2使用举例 2.4-isxdigit()2.4.1描述 2.5-islower()2.5.1描述2.5.2使用举例 2.6-isupper()…

jenkins容器中安装python遇到问题

在Jenkins容器中安装配置Python时遇到问题 执行./configure --prefix/opt/python3/时遇到configure: error: no acceptable C compiler found in $PATH 这个问题就是缺少gcc编译环境。将gcc安装上即可&#xff1a; yum install -y gcc##前提是容器里的系统是cenos才可以&#…

专升本 C语言笔记-06 常用的3种输入输出函数

1.scanf() 与 printf() 的使用 scanf() 格式化输入数据 格式:scanf("格式控制字符串",参数地址列表) scanf("%d,%d,%d",&a,&b,&c); printf("a %d\n",a); printf("b %d\n",b); printf("c %d\n",c); 注意 注…

(网络安全)一款强大的逆向分析工具,开源!

工具介绍 Ghidra 是由美国国家安全局&#xff08;NSA&#xff09;研究部门开发的软件逆向工程&#xff08;SRE&#xff09;套件&#xff0c;用于支持网络安全任务。包括一套功能齐全的高端软件分析工具&#xff0c;使用户能够在各种平台(Windows、Mac OS和Linux)分析编译后的代…

详解VXLAN

海翎光电的小编今天为大家介绍了什么是VXLAN&#xff0c;以及VXLAN的基本概念和工作原理。 什么是VXLAN VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;&#xff0c;是由IETF定义的NVO3&#xff08;Network Virtualization ov…

深入解析FastAPI多线程:加速代码执行效率

在现代网络应用中&#xff0c;高性能和快速响应是至关重要的&#xff0c;Python 的 FastAPI 框架以其出色的性能和简单易用的特点&#xff0c;成为了许多开发者的首选。然而&#xff0c;在某些场景下&#xff0c;单线程运行可能无法满足需求&#xff0c;这时候就需要考虑使用多…

RPC通信原理(一)

RPC通信原理 RPC的概念 如果现在我有一个电商项目&#xff0c;用户要查询订单&#xff0c;自然而然是通过Service接口来调用订单的实现类。 我们把用户模块和订单模块都放在一起&#xff0c;打包成一个war包&#xff0c;然后再tomcat上运行&#xff0c;tomcat占有一个进程&am…

vue模板语法介绍及内置指令用法

1、文本差值&#xff08;大括号、v-text、v-htm指令&#xff09; 最基本的数据绑定就是文本差值&#xff0c;格式为“Mustache”语法&#xff08;双大括号&#xff09;&#xff1b; 双大括号只能解析文本不能解析html&#xff0c;如需解析html则需使用v-html指令&#xff1b;…

【四 (2)数据可视化之 Matplotlib 常用图表及代码实现 】

目录 文章导航一、介绍二、安装Matplotlib三、导入Matplotlib四、设置可以中文显示四、常用图形1、散点图&#xff08;Scatter Plot&#xff09;2.1、线性图&#xff08;Line Plot&#xff09;2.2、堆叠折线图2.3、多图例折线图3.1、柱状图/条形图&#xff08;Bar Chart&#x…

AI基础知识问答(1)

1.什么是线性判别分析法&#xff08;FDA&#xff09;&#xff1f; 线性判别分析是一种对于监督数据降维的经典方法。通过对数据标准化&#xff0c;求得类内散度矩阵和类间散度矩阵&#xff0c;寻找一个投影矩阵W&#xff0c;使得同类样例的投影点尽可能接近&#xff0c;异类样…