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

该文章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);//这里不识别 numreturn;
}
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);				//答案为 7printf("getO = %d\n",getO());		//答案为 18printf("getG = %d\n",getG());		//答案为 20printf("%d\n",va*getO()*getG());	//答案为 2520
    }
    

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

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

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

相关文章

想做好国际现货黄金行情交易 请从这样的预期开始

国际现货黄金行情以多变而著称&#xff0c;而这样多变的行情&#xff0c;又由于其趋势稳定&#xff0c;而深受投资者喜爱。我们看近期&#xff0c;国际现货黄金行情不断上涨&#xff0c;短线呈现出很强的上涨趋势&#xff0c;这正是投资者入场交易的好时机&#xff0c;但是要做…

目标检测——PP-YOLOE-R算法解读

PP-YOLO系列&#xff0c;均是基于百度自研PaddlePaddle深度学习框架发布的算法&#xff0c;2020年基于YOLOv3改进发布PP-YOLO&#xff0c;2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet&#xff0c;2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列&#xff0c;所以放一起解…

从头手搓一台ros2复合机器人(带机械臂)

一.前言 大家好呀&#xff0c;从本小节开始我们就步入了仿真篇&#xff0c;主要对机器人仿真进行介绍与操作&#xff0c;当然仿真有优点也有缺陷&#xff0c;基于对此学习&#xff0c;我们可以对上几小节创建的小车模型模拟硬件的特性&#xff0c; 比如&#xff1a; 有多重…

洛谷[NOIP2016 提高组] 玩具谜题

[NOIP2016 提高组] 玩具谜题 题目背景 NOIP2016 提高组 D1T1 题目描述 小南有一套可爱的玩具小人&#xff0c;它们各有不同的职业。 有一天&#xff0c;这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈&#xff0c;它们有的面朝圈内&#xff0c;有的面…

JetBrains学生包续期

Pycharm进入显示your license has expired 这个意思是你的许可过期了&#xff0c;重新输入最新的激活码就可以了。 1. 说明我的JetBrains学生包需要进行续期了。首先登录JetBrains官网打开个人主页&#xff0c;点击Renew my Education Pack 2. 然后填写一系列信息&#xff0c;…

VR历史建筑漫游介绍|虚拟现实体验店|VR设备购买

VR历史建筑漫游是一种利用虚拟现实技术&#xff0c;让用户可以身临其境地参观和探索历史建筑的体验。通过VR头显和相关设备&#xff0c;用户可以在虚拟环境中自由移动和互动&#xff0c;感受历史建筑的真实氛围和文化内涵。 在VR历史建筑漫游中&#xff0c;您可以选择不同的历史…

手机备忘录怎么导出到电脑,如何将手机备忘录导出到电脑

备忘录是我们日常生活和工作中常用的工具之一&#xff0c;我们可以在手机上轻松地记录重要的事务、想法和灵感。然而&#xff0c;在某些情况下&#xff0c;我们可能需要将手机备忘录导出到电脑进行更详细的整理和管理。那么&#xff0c;手机备忘录怎么导出到电脑&#xff0c;如…

开箱即用之 windows部署jdk、设置nginx、jar自启

jdk安装 官网下载对应的安装包&#xff0c;解压之后放在本地指定的文件夹下 传送门https://www.oracle.com/java/technologies/downloads/#jdk21-windows 我比较喜欢下载zip方式的&#xff0c;解压之后直接能用&#xff0c;不需要安装了 配置环境 JAVA_HOME 添加path路径 …

MySQL数据导入的方式介绍

MySQL数据库中的数据导入是一个常见操作&#xff0c;它涉及将数据从外部源转移到MySQL数据库表中。在本教程中&#xff0c;我们将探讨几种常见的数据导入方式&#xff0c;包括它们的特点、使用场景以及简单的示例。 1. 命令行导入 使用MySQL命令行工具mysql是导入数据的…

有关【指针运算】的经典笔试题

题目1&#xff1a; #include <stdio.h>int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } //程序的输出结果是什么&#xff1f; 2 5解析&#xff1a; 代码的内存布局如图&#xff1a…

Nutanix 国产化替代|一文了解 SmartX 超融合替代可行性与迁移方案

2022 年 8 月 19 日&#xff0c;Nutanix&#xff08;路坦力&#xff09;宣布中国市场自 2023 财年起将转型为合作伙伴销售主导模式&#xff0c;引起了广泛关注&#xff1b;同时结合当前 IT 基础架构的国产化趋势背景&#xff0c;不少正在使用和考虑使用 Nutanix 产品的企业开始…

编译原理-实现LR语法分析器——沐雨先生

实验任务&#xff1a; 实现LR语法分析器 实验要求&#xff1a; 根据编译原理理论课教材中例3.22给出的算术表达式文法以及该文法的LR分析表&#xff0c;用C语言编写接受算术表达式为输入的语法分析器&#xff0c;以控制台&#xff08;或文本文件&#xff0c;也可以结合词法分…

C语言种sizeof()和strlen的区别

sizeof 是 C 语言内置的操作符关键字&#xff0c;而 strlen 是 C 语言库函数&#xff1b; sizeof 仅用于计算数据类型的大小或者变量的大小&#xff0c;而 strlen 只能以结尾为 \0 的字符串作为参数&#xff1b; 编译器在编译时就计算出了 sizeof 的结果&#xff0c;而 strlen …

Spring Security的开发

文章目录 1,介绍2, 核心流程3, 核心原理3.1 过滤器链机制3.2 主体3.3 认证3.4 授权3.5 流程图4, 核心对象4.1 UserDetailsService 接口4.2 PasswordEncoder 接口4.3 hasAuthority方法4.4 hasAnyAuthority方法4.5 hasRole方法4.5 hasAnyRole方法5, 核心注解5.1 @PreAuthorize5.1…

【Linux】系统开启和关闭过程

Linux 系统启动过程 BIOS 自检&#xff1a;在计算机开机时&#xff0c;BIOS 会进行自检&#xff0c;检查硬件设备是否正常。 加载引导程序&#xff1a;BIOS 自检完成后&#xff0c;会加载引导程序&#xff0c;如 GRUB、LILO 等。引导程序会加载内核和初始化 RAM 磁盘&#xff…

想入门Web测试,看这篇文章!

今天要谈的是很多软件测试工程师都需要面对的——Web测试 不管你是处在二十不惑的青春有你阶段还是三十而已的乘风破浪阶段我们都需要面对“Web测试”。 Web测试其实有以下几个方面&#xff1a; 1、页面测试 大多数的Web网站的网页都是html语言编写的&#xff0c;测试工程师…

3.3 RK3399项目开发实录-板载Ubuntu系统的使用(wulianjishu666)

嵌入式物联网常用90款传感器开发例程。链接&#xff1a;https://pan.baidu.com/s/1oisHMZXDzKqa4EspY83V-A?pwdo5f4 1. 介绍 Ubuntu 使用手册是针对 Firefly 官方发布的 Ubuntu 系统固件特性所编写&#xff0c;适用于 Ubuntu Desktop 与 Minimal 系统&#xff0c;部分与 UI 显…

开源文本挖掘引擎:情感分析|API接口|可私有化部署

中文的表达方式五花八门&#xff0c;比如成语、俗语、还有那些让人哭笑不得的双关语&#xff0c;这些都让情感分析变得复杂。再者&#xff0c;中文里头的情感表达很多时候得看上下文&#xff0c;一句话放在不同的情景里&#xff0c;意思可能就大相径庭了。 中文里面的否定和讽…

openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优

文章目录 openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优245.1 算子级调优245.1.1 算子级调优介绍245.1.2 算子级调优示例 openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优 SQL调优是一个不断分析与尝试的过程&#x…

Vector Magic:矢量图像转换神器,轻松驾驭Mac与Win双平台

在数字化时代&#xff0c;图像已经成为我们生活和工作中不可或缺的一部分。无论是设计师、艺术家&#xff0c;还是普通用户&#xff0c;都对图像质量有着极高的要求。而矢量图像&#xff0c;以其清晰度高、可无限放大的特点&#xff0c;逐渐受到广大用户的青睐。今天&#xff0…