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

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.mfbz.cn/a/472732.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Web MVC入门(5)

响应 在我们前面的代码例子中, 都已经设置了响应数据Http响应结果可以是数据, 也可以是静态页面, 也可以针对响应设置状态码, Header信息等. 返回静态页面 创建前端页面index.html(注意路径) html代码如下: <!DOCTYPE html> <html lang"en"> <hea…

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

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

Vue 中预加载组件

在 Vue 中&#xff0c;利用 VueRouter 可以轻松的实现两个组件&#xff08;页面&#xff09;之间的切换&#xff0c;有个常用的设计就是需要在登录页登录后跳转至一个内容页&#xff0c;通常的做法是在登录校验完成之后立即切换路由至内容页&#xff0c;接着内容页发送网络请求…

极简生活|2024年让自己越来越好的18个极简好习惯

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 转眼间已经进入了2024年&#xff0c;新的一年&#xff0c;新的开始。 俗话说&#xff1a;百尺高台起于垒土&#xff0c;千里之堤毁于蚁穴。 好习惯积累的越多&#xff0c;坏习惯越来越少&#xff0c;我们的生活才能越…

Iterator对象功能学习

package config;import java.util.Iterator; import java.util.Properties; import java.util.Set;/*** 这个类演示了如何使用Properties类来存储和访问键值对。* Properties类继承自Hashtable&#xff0c;因此它可以用来存储键值对数据&#xff0c;且支持同步。*/ public clas…

MySQL介绍

一、MySQL数据库介绍 1、发展史 1996年 MySQL1.0 2008年1月16日 Sun公司收购了 MySQL 2009年4月20日 Oracle收购了Sun公司 MySQL是一种开放源代码的关系型数据库管理系统 使用最常用的数据库管理语言 SQL&#xff08;结构化查询语言&#xff09; MySQL是开放源代码的 因此所有…

基于Springboot的员工健康管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的员工健康管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【c++】c++基本语法知识-命名空间-输入输出-缺省参数

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;c_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.命名空间 1.2 命名空间定义 1.3 命名空间使用 命名空间的三种使用方式 2.C输入&输出 std命名空间的使用惯例 3.缺省参数 3…

Win11初始化系统遇一文解决

这个是目录 一、设置内的初始化无法使用时&#xff0c;使用以下工具二、将桌面移动到D盘三、解决win11桌面右键创建只有一个带盾牌的文件夹问题四、win11 系统停止更新五、office安装1、使用的是 Office Tool plus2、使用WPS 六、D盘有感叹号七、打开组策略编辑器(gpedit.msc)失…

【Docker】-- 如何安装docker

一、安装docker 首先要安装一个yum工具 yum install -y yum-utils 安装成功后&#xff0c;执行命令&#xff0c;配置Docker的yum源&#xff1a; yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 最后&#xff0c;执行命令&#x…

Windows 安装 Graalvm 环境(JDK 22)

Windows 安装 Graalvm 环境 系统&#xff1a;Windows 11 官方参考指南&#xff1a;https://www.graalvm.org/jdk22/docs/getting-started/windows/ 安装 Graalvm & 下载 native-image 下载 Graalvm 并安装 下载的 SDK 选择最新版&#xff08;JDK 22&#xff09;&#xff…

UE4_官方动画内容示例1.3_ 运动混合空间(Locomotion BlendSpace)

如何使用运动&#xff08;Locomotion&#xff09;混合空间将Actor在不同方向上及不同速度的运动混合起来。&#xff08;例如&#xff0c;展示了一个混合了以不同速度向后、前、左和右走路/跑步动作的Actor&#xff09;。 一、相关知识点&#xff1a; 混合空间是允许根据多个输…

《汽车数据安全若干问题合规实践指南》正式发布(百度盘下载)

指南针对汽车数据安全的重要合规内容&#xff0c;结合汽车行业特有场景&#xff0c;参考行业最佳实践&#xff0c;提出合规实践建议。指南旨在进一步提高汽车行业数据安全保护水平&#xff0c;增强汽车企业数据安全合规保障能力&#xff0c;推动汽车数据价值安全使用&#xff0…

初始Java篇(JavaSE基础语法)(2)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 目录 逻辑控制 顺序结构 分支结构 if语句 switch 语句 循环结构 while 循环 for 循环 do while 循环 输入输出 输出到控制台 从键盘输入 …

AIGC——ComfyUI工作流搭建、导入与常用工作流下载

工作流 ComfyUI工作流是一个基于图形节点编辑器的工作流程&#xff0c;通过拖拽各种节点到画布上&#xff0c;连接节点之间的关系&#xff0c;构建从加载模型到生成图像的流程。每个节点代表一个与Stable Diffusion相关的模型或功能&#xff0c;节点之间通过连线传递图片信息。…

蓝桥杯-数的潜能-求快速幂

题目 思路 --将数字拆分成加和的形式&#xff0c;并且相乘。数据范围到10的18次方&#xff0c;暴力肯定不行&#xff0c;要找规律。拆分成1肯定不行&#xff0c;对乘法没有贡献&#xff0c;2可以&#xff0c;3也可以&#xff0c;4、5、6等大于3的数字都可以用2和3来表示。所以…

【堆】Top-K问题

标题&#xff1a;C语言库函数scanf&#xff08;&#xff09;解读 水墨不写bug &#xff08;图片来源于网络&#xff09; 正文开始&#xff1a; Top-K问题是一类问题的统称&#xff1a; 即根据对象的某一属性&#xff0c;找出这个属性最突出的K个对象&#xff0c;并且通常对象…

简单了解多线程

并发和并行 并发&#xff1a; 在同一时刻&#xff0c;多个指令在单一CPU上交替指向 并行&#xff1a;在同一时刻&#xff0c;多个指令在多个CPU上同时执行 2核4线程&#xff0c;4核8线程&#xff0c;8核16线程&#xff0c;16核32线程 基础实现线程的方式 Thread :继承类 &…

OpenJDK11的安装及配置

OpenJDK11的安装及配置: 下载链接&#xff1a;http://jdk.java.net/archive/ 1. 下载 点击链接下载OpenJDK11的zip压缩文件** 选择Windows版本 解压 解压成功。 2. 环境配置 打开设置----选择相关设置中的高级系统设置 选择高级—环境变量 系统变量 下添加JAVA_HOME …