《C语言深度剖析》---------关键字(1)

news2024/11/24 0:45:06

1.双击实质--->加载内存

windows系统里面,双击的本质就是运行程序,把程序加载到内存里面;

任何程序运行的时候都必须加载到内存里面;

程序没有运行之前在硬盘里面,为什么程序运行之前必须加载到内存里面呢?

这个时候就有必要了解一下冯诺依曼体系结构:

我们输入的数据要到内存里面,经过CPU的处理和分析,最后显示到输出设备上面;

为什么一定要加载到内存上面呢,因为CPU访问内存的速度非常快,如果要是放到硬盘里面;

CPU访问硬盘的速度就会比较慢了,因此加载了以后就要放到内存里面。

2.变量的实质

(1)所有变量都在内存里面的某个位置开辟空间,变量在运行的时候才会开辟空间,程序运行的时候才会加载到内存里面,程序运行的时候变量已经在内存里面了,因此变量只能够在内存里面开辟空间,而不能在硬盘等其他的位置开辟空间。

(2)因为内存里面的数据要被临时存储,所以有了变量的存在;

(3)声明和定义:定义变量,定义只能定义一次,变量的定义是要开辟空间的;而声明相当于一个告知的作用,可以进行多次的声明;

3.生命周期&&作用域

生命周期:相当于一个时间概念,什么时候被开辟,什么时候被释放;

作用域:该变量的有效区域,局部变量在自己的代码块是有效的,全局变量整个程序都是有效的;

4.最宽宏大量的关键字------auto

auto关键字一般只修饰局部变量,而且一般省略不写,这个关键字已经很老套了,一般不使用;

5.最快的关键字-----register

寄存器,cache属于CPU范畴,距离CPU越近,代价成本越高,存储本身是存在分级的,任何一种硬件,都在充当着上游硬件的缓存,这样方便CPU访问数据的时候,降低成本,提高效率;

CPU内部集成了一组存储硬件,我们把这组硬件叫做寄存器;

register就是把变量放到寄存器里面,提高效率,局部变量(存在的时间比较短,如果是全局变量,使用register修饰的话,就会长时间占用空间),变量不会被写入,变量被高频读取(这个可以提高效率),这几种情况下都可以使用register修饰;

因此,我们称register为最快的关键字,相信你也知道了原因;

对于寄存器上面的变量,我们尽量不要使用取地址,图可见寄存器变量取地址程序会报错;但是我们可以进行写入,这个地方的意思就是比如我们想要对变量a=10进行加加操作,CPU具有运算的能力,计算了成为11以后要重新写回到内存里面,因此也就是我们可以对他进行赋值;

6.最名不符实的关键字-----static

(1)多文件系统:

首先要亮出一个结论:所有的变量在进行声明的时候,不能设置初始值!

我们可以尝试在vs里面新建2个.c文件,如果我们在文件1里面定义一个函数,我们在文件2里面不进行声明也是可以调用的,这个时候编译器警告,但是能够运行;

但是如果我们在文件1里面定义一个变量,这个时候就不能够在文件2里面打印输出这个变量的值,我们如果想要打印输出,就需要进行声明外部符号,使用extern关键字,但是使用extern声明外部符号的时候,不能对这个变量进行赋值,因为生命的时候不会开辟空间的,但是我们进行赋值就要把这个值放到变量对应的内存空间里面去,显然是会报错的,但是我们定义的时候开辟了内存空间,所以我们应该定义变量的时候对其进行初始化,声明的时候不给初始值;

(2)源文件&&头文件

相信有很多的初学者经常使用的是源文件,不是很清楚源文件和头文件的区别,下面我通过一些例子向你细细说到:
我们通过上面的多文件系统就可以了解到这个不同的文件使用并非在自己的文件里面定义的变量的时候,都需要声明外部变量符号,这个时候就需要考虑一个问题,如果我们搞一个项目的话,这个时候就会有很多的源文件,难道每个源文件都需要进行声明嘛,这样做的话未必也就太麻烦了吧,而且如果我们这样做,后期我们进行项目的维护的时候就会变得比较困难,例如我们想要修改某个变量或者函数;

这个时候源文件就出现了,在源文件里面我们可以把函数的声明,变量的声明放一份,其他文件就可以只需要包含头文件就可以了;

我们使用尖括号包含库里面的头文件,使用双引号包含自己的头文件

但是这个时候可能会出现头文件会被多次包含,我们只需要在头文件里面敲入#pragma once就可以解决这个问题了;

这个地方展示一个完整的使用案例:为了规范我们的代码风格,在进行变量的声明以及函数的声明的时候我们尽量加上extern关键字,声明函数的时候尽量加上参数的变量名字以及变量的类型,尽管进行函数的声明的时候只写函数参数的类型就足够了,我们尽量还是补充完整,规范自己的代码

(3)static修饰全局变量

我们通过上面的一系列的例子已经认识到了,全局变量是可以跨文件进行访问的,函数也是可以跨文件进行访问的,但是static这个时候就可以发挥自己的作用了

*static修饰全局变量之后,static修饰全局变量,只影响作用域,不影响生命周期;这个全局变量只有自己的文件可以访问,其他的文件不可以直接进行访问,一定要注意这里的“直接”两字,因为这个地方是不能直接进行访问,但是我们可以间接进行访问啊,并不是这个全局变量被static关键字修饰以后其他的文件就不能够进行访问了,下面通过一个具体的实例来了解一下吧:

下面我们看一下我们如何间接访问:

(4)static修饰函数

函数被static修饰了以后,这个函数不能够被其他的文件访问;但是同理,只是不能够被直接访问,是可以被间接访问的,就是通过其他的函数调用这个被static修饰的函数,以达到访问的目的

(5)static修饰局部变量

我们都知道局部变量具有临时性,只有在自己的代码块里面才是有效的,如果我们static修饰局部变量,就可以改变局部变量的生命周期,不影响作用域(这个地方和全局变量恰好相反),相当于这个时候的局部变量具有了全局性,延长了其生命周期;但是作用域不变,就是如果你在主函数里面输出stativ修饰的变量的值,是无法打印输出的,因为尽管他被修饰了,作用域(作用的范围)还是只在函数的内部;

没有static修饰:

这个时候调用函数,创建变量,开辟空间,调用函数完成以后,这块空间就会被销毁,相当于i每一次都是从0开始进行加加;

加上static修饰之后:

局部变量具有了全局性,每次函数的调用完成以后就不会被销毁变量空间,因此i能够从0开始,循环输出知道10停止;

(6)C程序地址空间

这个我们只需要理解为什么static修饰局部变量以后,他的生命周期具有了全局性,主要是变量的存储位置发生了改变,没有修饰之前的局部变量在栈区里面,被static修饰了以后,就在全局数据区,存储位置发生改变,是其生命周期变长的本质原因,栈区里面的数据存储就像手枪里面的弹夹,先进后出,后进先出,这个分别对应入栈,出栈2个动作,通过这张图我们也可以看出来,栈区里面的变量定义是从高地址到低地址,而堆区恰恰与之相反;

7.sizeof关键字

sizeof用来求不同的数据类型开辟的内存空间的大小;因为程序设计有许多不同的场景,因此我们设计了不同的类型用来存储与之对应的数据,这样可以更加高效的利用空间;

sizeof不是函数,只是用来求不同的数据类型的大小,这个类型既可以是我们已知的C语言内置数据类型,也可以是我们自己定义的指针类型等等;如:

整形数据占4个字节;64位操作系统,指针大小8字节,数组里面4个int*类型的数据,sizeof(arr)求的是整个数组的大小,4*8=32字节的大小;

8.unsigned和singned关键字

这两个一个是有符号(signed),一个是无符号类型(unsigned);

整形在内存里面的存储

(1)计算机里面储存的是补码,补码经过符号位不变,其他位按位取反,得到的是我们的反码,反码加一,得到的是我们的原码,实际上进行加一操作的时候,符号位也是要进行的,但是一般我们不会遇到这么大的数据,因为要想让符号位加上1,就表示符号位后面的所有位都是进过位的,或者是和符号位相近的的位数发生了进位的操作,一般我们是遇不到的;

(2)存储的本质:

我们可以自己亲手实践一下,定义一个无符号的变量,但是把一个负数赋值给这个变量,我们大部分情况下都会认为无符号的变量里面怎么能够存放一个负数呢?当我们运行起来的时候,发现程序并不会报错,这个是因为定义变量的时候就会先进行空间的开辟,这个时候把已经转换成为补码的二进制序列存进去,存进去的时候已经是二进制的补码了,存的时候不会关注数据的类型,所以无符号的数据类型也是可以存放负数的;

我们定义一个变量就要在内存上面开辟一块空间,这个时候进行数据存的过程,存放数据的时候,我们是不关心这个数据是有符号的还是无符号的,计算机只是单纯的把数据的补码存进去就可以了,这个时候是不关心数据的类型的,但是当我们取数据的时候,就要关心他的数据类型,关心他是有符号还是无符号的,因为这个决定我们是否要关注他的符号位,以及原码反码补码之间的相互转换;因为如果是无符号的,我们就会直接进行转换,如果是有符号的,我们就要关心他的符号位,而且无符号的符号位也会当作数值位进行计算的;

(3)大小端:低位放在低地址,高位放在高地址就是小端存储,低位放在高地址,高位放在低地址就是大端存储;首先我们要有一个基本常识:在我们的vs stdio里面,打开我们的内存窗口,里面显示的是数据的内存排布,这个时候从上到下地址从高到低,从左到右,地址也是由高到低,概括起来就是左上高,右下低(这个里面的高低指的是地址的高低);如图所示

这个时候我们借助大小端理解一下数据在内存里面的存储,实际上面数据的存储和大小端是有关的,计算机存的时候,取的时候,都是按照自己的大端的规则或者小端的规则,所以我们看的数据是不受影响的,但是数据的存储还是经历了大小端的这个过程;

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

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

相关文章

免费的chatgpt网站(包含最新版4.0)

相信每个人在生活工作学习中都逃不过用chatgpt来解决一些问题,下面我长话短说,为大家简单介绍几款免费且好用的chatgpt网站 1、YesChat 网址:YesChat-ChatGPT4V Dalle3 Claude 3 All in One Free 第一个就给大家介绍一个狠角色,最…

万界星空科技铜杆加工行业生产管理MES系统

传统的铜管加工方法有: (1)铜管挤压加工技术(2)铜管上引连铸法(3)铜管(有缝)焊接生产技术(4)铸轧法生产精密铜管铸轧法 生产精密铜管是一种全新的生产工艺,…

154.乐理基础-和弦固定标记法(三)九音、十一音、十三音

如果到这五线谱还没记住还不认识的话去看102.五线谱-高音谱号与103.五线谱-低音谱号这两个里,这里面有五线谱对应的音名,对比着看 内容参考于:三分钟音乐社 上一个内容:153.和弦的织体 上一个内容里练习的答案: 接下…

开放签开源电子签章白皮书-简版

开放签开源电子签章白皮书-简版 一、摘要: 开放签电子签章团队源自于电子合同SaaS公司,立志于通过开源、开放的模式,结合团队十多年的行业经验,将电子签章产品更简单、更低门槛的推广到各行各业中。让电子签章应用更简单&#x…

31.HarmonyOS App(JAVA)鸿蒙系统app Service服务的用法

鸿蒙系统app Service服务的用法 后台任务调度和管控 HarmonyOS将应用的资源使用生命周期划分为前台、后台和挂起三个阶段。前台运行不受资源调度的约束,后台会根据应用业务的具体任务情况进行资源使用管理,在挂起状态时,会对应用的资源使用进…

2024年熔化焊接与热切割证模拟考试题库及熔化焊接与热切割理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年熔化焊接与热切割证模拟考试题库及熔化焊接与热切割理论考试试题是由安全生产模拟考试一点通提供,熔化焊接与热切割证模拟考试题库是根据熔化焊接与热切割最新版教材,熔化焊接与热切割大…

n皇后问题(典dfs )注意对角线状态判断

思路&#xff1a;用的dfs思想&#xff0c;第一种是全排列思路&#xff0c;和数字排列同样的步骤。要注意对对角线的判断。下面画了个图简单示意一下&#xff0c;但是 u 和 i 的位置变了&#xff0c;在代码里呈现不一样。明天再改吧。先睡了。 代码&#xff1a; #include<io…

IDE(集成开发环境)插件是安全开发的便捷方式之一

开发人员每天都使用插件&#xff0c;插件的功能在于简化开发流程&#xff0c;例如自动检测所有特殊字符&#xff08;如“;”、“:”&#xff09;或语法合规性。创建插件的目的本身就是为了让开发人员能够在编写代码时检测漏洞&#xff0c;并在无需离开 IDE 环境的情况下立即修复…

STM32CubeMX学习笔记25---FreeRTOS信号量

一、信号量简介 信号量用于同步&#xff0c;任务间或者任务和中断间同步 互斥量用户互锁&#xff0c;用于保护同时只能有一个任务访问的资源&#xff0c;为资源上一把锁。 二值信号量&#xff1a;同步。如果存在两个线程&#xff0c;为线程1和线程2&#xff0c;如果线程1发送了…

大载重无人机基础技术,研发一款50KG负重六旋翼无人机技术及成本分析

六旋翼无人机是一种多旋翼无人机&#xff0c;具有六个旋翼&#xff0c;通常呈“X”形布局。它采用电动串列式结构&#xff0c;具有垂直起降、悬停、前飞、后飞、侧飞、俯仰、翻滚等多种飞行动作的能力。六旋翼无人机通常被用于航拍、农业植保、环境监测、地形测绘等领域。 六旋…

PolarDN MISC(简单)大礼包 :详细思路过程

0和255 题目给了俩个文件&#xff0c;一个.txt,一个.py .txt文件中包含0和255 一个字节有八位&#xff0c;每一位只能储存1或0&#xff0c;计算机只懂二进制&#xff0c;所以就是2的八次方&#xff0c;又计算机规定从0开始计数&#xff0c;所以是0至255 考虑用编码转换工具将其…

Android: Gradle 命令

一、查看整个项目依赖传递关系 x.x.x (*) 该依赖已经有了&#xff0c;将不再重复依赖。x.x.x -> x.x.x 该依赖的版本被箭头所指的版本代替。x.x.x -> x.x.x(*) 该依赖的版本被箭头所指的版本代替&#xff0c;并且该依赖已经有了&#xff0c;不再重复依赖。 1. gradlew ap…

redis常用五大数据类型

目录 Key 字符串String 常用命令 列表List 常用命令 集合Set 常用命令 Hash哈希 键值对集合 有序集合Zset Redis新数据类型 Key set key value...添加keykeys *查看当前库中所有的keyexist key该key是否存在type keykey的类型del key删除keyunlink key根据value选择非阻塞…

基于springboot+vue的火锅店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

2024.3.16-408学习笔记-C-数据在内存中的存储

1、整数型存储 整数型存储就是所有整型家族里的数据类型的存储方式&#xff0c;也就是说包含了字符类型的存储&#xff08;因为字符的操作符的返回值是ASCII码值&#xff0c;故实际上存储的是整数&#xff09;。 1.1、有符号整数 有符号整数包含char&#xff0c;short&#x…

Combining external-latent attention for medical image segmentation

结合外部潜在注意的医学图像分割 摘要 注意机制是提高医学图像分割性能的新切入点。如何合理分配权重是注意力机制的关键,目前流行的方法包括全局压缩和使用自注意操作的非局部信息交互。然而,这些方法过于关注外部特征,缺乏对潜在特征的开发。全局压缩方法通过全局均值或…

(一)基于IDEA的JAVA基础3

通过之前的内容&#xff0c;我们在建好的文件夹下建一个java文件&#xff0c;我们来在IDEA中写一下之前用记事本写的helloworld&#xff0c;我们先看一下java代码的规范: 1.java程序文件名一定要有意义&#xff0c;首字母一定要大写。 2.class后面的名字:由大小写字母&#x…

【NTN 卫星通信】 车辆物联网设备通过NTN和TN切换的应用场景

1 场景描述 对于有两个3GPP无线接入网服务的大面积农田和农场&#xff0c;物联网设备可以通过NTN和TN接入网同时受益于5G系统的双转向数据连接能力。   在这个用例中&#xff0c;我们有一个广域的农业自动化应用系统来控制农业车辆&#xff0c;例如&#xff0c;一个装有数百个…

遇见AI暴雨受邀参加NVIDIA GTC 2024

2024年3月18日&#xff0c;备受瞩目全球科技盛会——2024 GTC在美国加州圣何塞拉开帷幕&#xff0c;此次大会旨在展示最新的GPU&#xff08;图形处理单元&#xff09;技术和应用&#xff0c;以及人工智能、数据科学、深度学习、虚拟化等领域的创新和发展。作为NVIDIA多年的战略…

浅尝大菠萝Pinia

1、pinia简介 Pinia&#xff08;发音为 /piːnjʌ/&#xff0c;类似于英语中的“peenya”&#xff09;是最接近有效包名 pia&#xff08;西班牙语中的_pineapple_&#xff09;的词。 Pinia 是由 Vue.js 团队成员开发&#xff0c;新一代的状态管理器&#xff0c;即 Vuex5.x。 …