内外部函数静态变量全局变量

news2024/12/26 21:18:20

1、函数(封装、复用)

功能性:最基本的特性;
扩展性:对于时刻变化的需求易于扩展;
维护性:对于时刻变化的需求易于维护,易于编码变更;
封装性:不要把所有的代码都写到一个文件或者一个函数里边去 模块 函数;
可读性:写的代码让人容易理解,要求足够的注释、结构清晰、多使用宏定义、枚举类型等。

1.1、函数的实际参数与形式参数

函数参数分为形参和实参两种,作用是实现数据传送。
形参出现在函数定义中,只能在该函数体内使用。发生函数调用时,调用函数把实参的值复制1份,传送给被调用函数的形参,从而实现调用函数向被调用函数向被调用函数的数据传送。

1.2、数组作为函数参数

为什么C语言创造者在设计函数时,当数组作为实际参数的时候,函数的形式参数会默认退化为指针类型?
如果传的是整个数组,调用又会开辟空间,栈内存会耗费非常快。作为指针会节省内存空间,地址或者指针只占用有限的内存空间(一般32位机器上只占用4个字节,64位机器上所有的指针类型占用空间,都是8字节)
传数组的时候没有必要完全复制实际参数,是需要将数组的首地址或者指针传入即可。因为数组的其他元素,可通过首地址+偏移找到,所以也要传递数组的大小。

1.3、函数的递归调用

企业编码规范中,一般要求尽量避免使用递归!

1.4、内部变量与外部变量

C语言中所有的变量都有自己的作用域。变量说明的位置不同,其作用域也不同,据此将C语言中的变量分为内部变量和外部变量。

在一个函数内部说明的变量是内部变量,它只在该函数范围内有效。也就是说,只有在包含变量说明的函数内部,才能使用被说明的变量,在此函数之外就不能使用这些变量了。所以内部变量也称“局部变量”。

关于局部变量的作用域还要说明以下几点:
1、主函数main()中定义的内部变量,也只能在主函数中使用,其他函数不能使用。同时,主函数中也不能使用其他函数中定义的内部变量。因为主函数也是一个函数,与其他函数是平行关系。这一点是与其他语言不同的,应予注意。
2、形参变量也是内部变量,属于被调用函数;实参变量,则是调用函数的内部变量。
3、允许在不同的函数中使用相同的函数名,它们代表的对象,分配不同的单元,互不干扰,也不会发生混淆。
4、在复合语句中也可定义变量,其作用域只在复合语句范围内。

尽量少使用全局变量,即使使用了全局变量也进行把它封装起来!
全局变量多了,维护性差!全局变量作用域是整个程序,谁都可以改!

1.5、extern关键字的使用

总结:
1、头文件一般是做外部变量以及外部函数声明用的,如果本文件的一些变量或者函数想给“别人”用的话,就 需要将这些变量或者函数声明到其对应的头文件中。
2、头文件中不建议定义变量!(容易产生变量重定义的错误)
3、变量的声明和定义之间的区别:
变量的定义是需要给变量分配内存空间的,并且可以初始化;
变量的声明是告诉编译器,我有这个变量存在,并不给变量分配内存空间,因此也就不能在声明的时候进行初始化赋值等操作。

1.6、外部函数与内部函数

变量的声明和定义的区别:
声明不分配内存空间,变量定义分配内存空间。

变量定义在头文件中好不好?
首先,编码规范规定,变量的定义一定放在源文件中,声明在头文件。

防止头文件重复包含,应该怎么做?(头文件使用#ifndef #define #endif作用 )
头文件展开多次,变量会多次定义。

2、实践案例

3、内存模型(memory layout)

3.1、内存类型的划分

Stack 栈区(非staic的局部变量,函数参数)声明周期是局部变量定义开始到函数结束。
Heap 堆区(malloc,calloc,realloc等动态分配的内存)声明周期是从malloc动态开辟空间开始,到调用free结束。
静态全局变量(静态变量,全局变量,常量)声明周期是从静态变量,全局变量,常量定义开始,到程序结束。(.bss .data .rodata)
代码区(存放函数体的二进制代码)用于存储程序编译连接后生成的二进制机器码指令的内存区域只读不可以更改。(.text)

在这里插入图片描述其中text表示只读区(.text和.rodata),data为.data初始化的全局变量或静态变量,.bss表示未初始化全局变量或静态变量。dec为前三者的和,hex为dec列的16进制表示。

3.2、RAM和ROM,Flash Memory的物理特性y

RAM又称随机存取器,存储的内容可通过指令随机读写访问。RAM中的存储的数据在掉电是会丢失,因而只能在开机运行时存储数据。其中RAM又可以分为两种,一种时Dynamic RAM(DRAM 动态随机存储器),另一种是Static RAM(SRAM,静态随机存储器)。

ROM又称只读存储器,只能从里面读出数据而不能任意写入数据。具有掉电后数据可保持不变的优点。因此常用存放一次性写入的程序和数据,比如主板的BIOS程序就是ROM存储器。

Flash Memory 由于ROM具有不易更改的特性,后面就发展了Flash Memory。Flash Memory不仅具有ROM掉电不丢失数据的特点,又可以在需要的时候对数据进行更改,不过价格比ROM高。

不同数据的存放位置:
由前面的分析我们知道,代码区和常量区的内容是不允许被修改的,ROM(STM32就是Flash Memory)也是不允许被修改的,所以代码区和常量区的内容编译后存储在ROM中。
栈、堆、全局区(.bss段、.data段)都是存放在RAM中
嵌入式中RAM资源比ROM更紧缺!

面试:
1、一个嵌入式系统欢迎语句应该如何定义 下面哪种更好?为什么?
char welcome[] = “welcome”; //.data中

const welcome[] = “welcome”; //.reodata或者text 加上const更好
char* welcome = “welcome”; //.reodata或者text 加上const更好
const char* welcome = “welcome”; //.reodata或者text 加上const更好

首先,在嵌入式系统RAM资源比ROM资源更紧缺。
第一种变量 占据栈资源,存放在RAM中。
第二种是常量 占据在静态全局变量中.rodata,存放在ROM中。
所以第二种更好。

2、char* welcome = “welcome”;
(补充:以上写法和char welcome[] = “welcome”; 两种写法完全不一样 可以通过welcome[0]='D’修改)
可以使用welcome[0] = ‘D’;去修改welcome指向的字符型吗?
不能,因为welcome指向的字符串存放在.rodata(只读)中,不允许修改。

3、某个局部变量定义为Size巨大的数据和结构体,好吗?为什么?
不好,局部变量是分配Stack区,RAM中,空间有限,很有可能造成栈溢出问题。

4、实践作业

修改图形成变量,查看割内存占用大小。

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

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

相关文章

G1回收器:区域化分代式

G1回收器概述 既然我们己经有了前面几个强大的GC,为什么还要发布Garbage First(G1)GC? 原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有GC就不能保证应用程序正常进行,而经常造成STW的GC又跟不上实际的需求&#xff0c…

Python 实验四 常用数据结构(1)

1.从键盘输入一个正整数列表,以一1结束,分别计算列表中奇数和偶数的和。 n int(input("请输入一个正整数:")) list [] while n ! -1:list.append(n)n int(input("请输入一个正整数:")) else:print("…

Linux下C/C++实现(网络流量分析-NTA)

网络流量分析(NTA - Network Traffic Analysis) 就是捕捉网络中流动的数据包,并通过查看包内部数据以及进行相关的协议、流量、分析、统计等,协助发现网络运行过程中出现的问题。通过监控和分析网络环境中的流量,来判断流量是用在…

electron编译环境搭建和第一个桌面应用例子

前言 Electron是基于Chromium和Node.js实现的,所以开发人员所需要使用到的前端技术主要包括以下方面: 1、Html、CSS、JavaScript、ES6 2、前端开发工具Vue、Angular、React等的一种 3、其他网络、缓存、通讯、系统、跟踪等前端技术 4、对Vscode编辑…

SpringCloud --- 认识微服务、服务拆分和远程调用

一、认识微服务 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢? 1.1、单体架构 单体架构:将业务的所有功能集中在一个项目中开发,…

C++学习(day5)

文章目录 一. 静态成员变量和函数(static)1. 静态成员变量2. 静态成员函数 二. 类的继承(inhert)1. 继承2. 继承的作用3. 一个类B继承类A4. 继承格式5. 子类会继承父类的所有成员6. 当父子类中出现同名的成员时7. **继承中构造函数和析构函数调用顺序**8…

反垃圾邮件产品测试评价方法示意图

声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品测试评价方法 测试环境 反垃圾邮件产品的典型测试环境如图1所示。 图1 反垃圾邮件产品典型测试环境示意图 测试设…

快速识别 SLI 指标的方法:VALET

SLI,Service Level Indicator,服务等级指标,其实就是我们选择哪些指标来衡量我们的稳定性。而 SLO,Service Level Objective,服务等级目标,指的就是我们设定的稳定性目标,比如“几个 9”这样的目…

Android音视频开发-OpenGL ES正交投影实现方法

本文实例为大家分享了OpenGL ES正交投影展示的具体代码,供大家参考,具体内容如下 绘制正方形 在最开始绘制的六边形里面好像看起来挺容易的,也没有出现什么问题,接下来不妨忘记前面绘制六边形的代码,让我们按照自己的…

设计模式——组件协作模式之模板方法模式

文章目录 前言一、“组件协作” 模式二、模板方法模式1、动机2、源码分析讲解①、结构化软件设计②、面向对象软件设计 三、模板方法模式定义四、结构要点总结 前言 一、“组件协作” 模式 现代软件专业分工之后的第一个结果是 “框架与应用程序的划分”,“组件协作…

部署LVS-NAT群集实验

一、 实验准备 负载调度器:内网关 ens33:192.168.109.12,外网关 ens37:12.0.0.1外网 Web节点服务器1:192.168.109.13 Web节点服务器2:192.168.109.14 NFS服务器:192.168.109.11 客户端&#xf…

C#基础学习--其他主题

目录 概述 字符串 使用StringBuilder类 把字符串解析为数据值 关于可空类型的更多内容 为可空类型赋值 使用空接合运算符 Main方法 文档注释 嵌套类型 析构函数和dispose模式 概述 再本章中会讲解一些重要的杂项知识 字符串 字符串是Unicode字符串数组 字符串是不可…

ISO-27145故障诊断说明

ISO-27145故障诊断说明 2.1 27145目录说明 ISO27145-1: 这里边介绍的是一般信息和用例定义; ISO27145-2: 这里边介绍的是与排放相关的通用数据规则,用于查询; ISO27145-3: 这里边主要介绍了支持的服务 12服务 14服务 19服务 22服务 31服务&…

【移动端网页布局】移动端网页布局基础概念 ⑧ ( 移动端页面布局方案 | 单独制作的移动端页面 - 主流 | 响应式页面兼容移动端 - 开发难度较大 )

文章目录 一、移动端页面布局方案1、单独制作的移动端页面2、响应式页面兼容移动端 一、移动端页面布局方案 移动端页面方案 : 单独制作的移动端页面 : 主流开发方案 , PC 端 与 移动端 访问的是不同的页面 , 目前的 京东 / 淘宝 等电商网站移动端页面采取的该方案 ;响应式页面…

高效编程----VSCode+ChatGPT插件

VSCode中使用ChatGPT插件 首先在VSCode中打开扩展面板,搜索ChatGPT,安装蓝色圈出插件,如图所示: 安装完成后,需要重启VSCode 注册账号,如图所示: 然后在ChatGPT对话框中输入信息即可使用&#…

[oeasy]python0137_相加运算_python之禅_import_this_显式转化

变量类型 相加运算 回忆上次内容 上次讲了是从键盘输入变量input 函数 可以有提示字符串需要有具体的变量接收输入的字符串 输入单个变量没有问题 但是输入两个变量之后一相加就非常离谱 怎么办呢?🤔 基本实验 回到 游乐场 做个 实验 两个整数 相加…

C++STL——map与set的模拟实现

map与set的模拟实现 map与set的部分源码参考改造红黑树红黑树的迭代器补全set与map的实现完整代码 map与set的部分源码参考 map和set的底层都是由红黑树实现的。 所以这里将上次实现的红黑树插入拿来用。 首先想一想,搜索二叉树不能修改值,因为会破坏整…

第十章 装饰者模式

文章目录 前言一、装饰者模式定义装饰者模式 UML图 二、装饰者模式解决星巴克咖啡订单完整代码Drink 抽象 饮料类Coffee 咖啡类继承 Drink 做一个缓冲层Espresso 意大利咖啡 继承 CoffeeLongBlack 咖啡ShortBlack 咖啡装饰者,调料牛奶巧克力豆浆咖啡店测试程序添加 …

01-yolo算法

要点: 归纳 YOLOv5 github 1 YOLO v1 1) 将一幅图像分成SxS个网格(grid cell),如果某个object的中心 落在这个网格中,则这个网格就负责预测这个object。 2)每个网格要预测B个bounding box,每个bounding box 除了要预测位置之…

TortoiseSVN使用-合并分支代码

文章目录 3.4.12 合并分支代码TortoiseSVN有2种合并方式演示场景1:(合并一个版本范围 Merge a range of revisions)演示场景2:(合并两个不同的树 Merge two different trees),不设置主分支版本演…