你真的了解C语言吗 (深度剖析C语言第一期)_c语言深度 剖析第一-程序员宅基地

技术标签: 2024年程序员学习  c语言  开发语言  

1.在没有加载到内存之前,程序在哪?

2.为什么所有的程序运行都要加载到内存当中?

通过学习我们可以知道,程序在没有加载到内存的时候放在硬盘,至于为什么程序运行的时候都必须放入硬盘是因为能提高运行效率,让程序更快运行。在此,我们需要了解一些硬件知识。**数据在传输的过程中大体要经历四个步骤,先由输入设备加载到内存,再通过CPU的处理后放到内存,最后刷新至输出设备。**我们先做了解,后续会再次学习冯诺依曼。

变量的声明和定义

变量的本质就是在内存中开辟一块空间用内存保存数据,处于代码块内的变量都是临时变量,运行的时候在内存栈区开辟。为什么定义变量本质都在内存开辟?因为变量在运行的时候才会开辟,而在程序运行之前都会加载到内存。当开辟变量的时候程序已经被加载到内存了。

定义是开辟空间,声明可以理解为告知。定义就是开辟变量,只能定义一次,声明可以声明多次。

关键字auto

通常用来修饰局部变量,该变量只在该代码块内有效,但是随着编译器的进步,auto已经可以被省略了。同样,我们通过程序来验证一下。

由此可见,当auto修饰局部变量的时候,程序是可以运行的,此时auto可以省略。由于auto关键字是年代很久远,我们现阶段基本不用,了解一下即可。

关键字register

什么是存储分级

首先我们需要了解具有存储能力的设备,寄存器,cache,内存,硬盘,软盘……距离CPU越近的存储单元,效率越高,单价成本越高。距离CPU越远的存储单元,效率越低,单价成本越低。对于任何一种硬件而言,它都充当这自己上游硬件的缓存,因此,CPU访问数据的时候以最小的成本达到最高的效率。

register修饰变量

register修饰变量就是尽量将该变量放入CPU的寄存器中,从而达到提高效率的目的。 哪些变量适合用register修饰呢?

1.局部变量,之所以不使用全局变量是一旦将全局变量放入寄存器中,它的作用域是整个工程,生命周期很长使得CPU寄存器被长时间占用。

2.不会被写入的变量。由之前所提及的冯诺依曼规则我们可以知道,数据写入将会被重新回写到内存中,然后重新加载。这样register就没有太大的意义。

3.高频被读取的变量。如果一个变量开辟空间时放在CPU的寄存器里面,那么我们读取变量的时候直接通过寄存器读取,直接通过CPU寄存器读取的效率是极高的。

那我们来思考一下,当我们用register修饰变量的时候,是在寄存器里面开辟的,能找到它的地址吗?想法归想法,写个程序测试一下。

实践证明,编译器报错,register修饰的变量在很多时候是在寄存器中开辟了一块空间而并非是在内存中开辟,而地址是内存上的地址,由此该变量是没有地址的,也是就不能通过取地址符号来找地址。

static关键字

多文件工程

首先我们可以思考一个问题,如果我们在一个工程里面创建两个源文件并将一个源文件里调用存放在另一个文件里的函数,会怎么样呢?是否会打印“别睡啦,快来和小生一起学习吧”呢?我们来测试一下:

程序运行可以发现,在同一个工程的两个不同源文件中,在一个文件里调用另一个文件中的函数是完全可以的,全局变量的作用域是整个工程,那我们如果在一个文件中使用另一个文件中的全局变量可以吗?我们来试一下。

**在此,我们需要用一个extern关键字来声明变量,注意我们这里是声明,并没有开辟空间。**因此我们在重拾C语言.c文件中只能用extern int num;声明该变量来自其他源文件。而不能用extern int num = 5;根本上说声明是没有开辟空间的但是存放变量是需要空间,因此这种写法是错误的。

但是如果项目比较大,文件一多,难道我们每个文件之前都需要声明外部变量或者函数吗?这样维护成本会变得极高,因此我们可以把所需外部函数、全局变量等放入一个新的头文件,可以减少维护成本。头文件基本上是被多个源文件包含,头文件可能会被重复包含,我们需要防止头文件被包含,我们可以在头文件之前加入#pragma once,那我们头文件一般包括什么呢?可以包含所有变量的声明,所有函数的声明,所有所需要的系统自带的头文件,#define ,typedef ,struct结构体等。

之前我们调用其他文件的函数时系统并未报错,但是为了让程序更加严谨,我们应该给来自外部的函数同样进行声明,那函数应该如何声明呢?函数的声明就是把函数的返回值函数的名称和函数的形参列表全部写上,不用写函数体。函数的定义本质也是在内存里开辟空间,变量保存的是数据,函数保存的就是代码,在上面这个问题,我们也可以用extern void show();来声明来自外部的函数。我们通过一个图来看一下:

通过上面的学习,我们知道,全局变量可以跨文件访问,函数也可以跨文件访问。但是在实际的应用当中,我们可能在某些时候不想让全局变量或者函数跨文件访问。这里我们就正式进入我们的主题——关键字:static。当我们用static修饰之前的全局变量num的时候我们改一下程序运行一下:

我们发现vs编译器报错,由此我们可以得出,static修饰全局变量的时候表示该变量只在本文件内被访问,不能被外部其他文件直接访问。那我们也可以猜想,当static修饰函数的时候,该函数是否也只是在该文件内可以被直接调用呢?我们可以试一下。

和原来的想法一样,直接报错哈哈,由此我们也可以得出一个结论,当static修饰函数的时候,该函数只能在本文件访问,不能在其他的文件内直接访问。但是可以通过嵌套的方式来访问。哈哈,是不是挺有趣的,我们来看一下:

因此我们以上的陈述是不能直接访问,但是可以通过函数嵌套的模式来间接访问。哈哈,确实挺有意思的。通过这个程序往深里面剖析,static是一个提供安全保护和项目维护的关键字。我们可以通过static把我们写的东西封装起来,用一个大函数包含, 这样就限制了他人对我们程序的修改,降低了暴露的接口,提高了程序的安全性,是不是很有意思呢?

我们再来看看下面这两个程序的对比:

**先看程序1:**

//程序1
#include <stdio.h>
static void fun()
{
int i = 0;
i++;
printf("%d ",i);
}
int main()
{
for(int i = 0 ; i <= 10; i++)
{
fun();
}
return 0;
}

直接看结果:

**再看程序2:**

//程序2
#include <stdio.h>
static void fun()
{
static int i = 0;
i++;
printf("%d ",i);
}
int main()
{
for(int i = 0;i <= 10 ;i++)
{
fun();
}
return 0;
}

直接看结果:

局部变量具有临时性,函数调用开辟空间并初始化,函数结束后释放空间,因此再第一个程序中,每次调用fun函数的时候每次都要为i开辟一块内存存放,然后函数结束后就销毁。那我们通过for循环的时候每次开辟的空间是否都是同一块空间呢?哈哈,我们同样可以来测试一下:

但是我们也可以测试一下,当我们再次运行该程序的时候地址就已经产生了变化,不信你试试。

我们再来看看第二个程序:static修饰局部变量的时候,i变量在运行的过程中出了函数并没有被释放,更改了临时变量的声明周期,因此i才会不断累加。我们先来认识一下C程序的地址空间:

局部变量被static修饰的时候开辟的空间位置变化,存储位置发生了变化,开辟到了静态区里面。因此生命周期变为了整个工程

到了这里只是一个最基础的部分啦,后续小生会不断更新更多的知识,你现在可以回答之前的那几个问题了吗?哈哈哈,大神们,如果觉得有所帮助别忘了给小生三连哦,你们的鼓励就是我最大的动力.

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-b4BftwhE-1712937482015)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2401_84264536/article/details/137698793

智能推荐

http隧道 java_使用java语言实现http隧道技术-程序员宅基地

文章浏览阅读119次。该楼层疑似违规已被系统折叠隐藏此楼查看此楼/***Getaparametervalue**@paramkeyString*@paramdefString*@returnString*/publicStringgetParameter(Stringkey,Stringdef){returnisStandalone?System.getProperty(ke..._java http隧道

Keepalived高可用+邮件告警_keepalived sendmail-程序员宅基地

文章浏览阅读913次。IP主机名备注192.168.117.14keepalived-master主节点192.168.117.15keepalived-slaver备节点192.168.117.100VIP1.主备节点均安装keepalived# yum install -y keepalived httpd2.主备节点均修改keepalived日志存放路径..._keepalived sendmail

SPFILE 错误导致数据库无法启动(ORA-01565)_ora01565 ora27046-程序员宅基地

文章浏览阅读469次。--==========================================--SPFILE错误导致数据库无法启动(ORA-01565)--========================================== SPFILE错误导致数据库无法启动 SQL> startup ORA-01078: failurein proce_ora01565 ora27046

功能测试基础知识(1)-程序员宅基地

文章浏览阅读6.1k次,点赞2次,收藏54次。功能测试基础知识总结_功能测试

postgresql 中文排序_pg中文排序-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏2次。pg 中文首字母排序_pg中文排序

[Mysql] CONVERT函数_mysql convert-程序员宅基地

文章浏览阅读3.1w次,点赞23次,收藏109次。本文主要讲解CONVERT函数_mysql convert

随便推点

HTML5与微信开发(2)-视频播放事件及API属性_微信开发者工具视频快进-程序员宅基地

文章浏览阅读8.6k次,点赞2次,收藏2次。HTML5 的视频播放事件想必大家已经期待很久了吧,在HTML4.1、4.0之前我们如果在网页上播放视频无外乎两种方法: 第一种:安装FLASH插件或者微软发布的插件 第二种:在本地安装播放器,在线播放组件之类的 因为并不是所有的浏览器都安装了FLASH插件,就算安装也不一定所有的都能安装成功。像苹果系统就是默认禁用FLASH的,安卓虽然一开始的时候支持FLASH,但是在安卓4.0以后也开始不_微信开发者工具视频快进

JedisConnectionException Connection Reset_jedisconnectionexception: java.net.socketexception-程序员宅基地

文章浏览阅读5.4k次,点赞3次,收藏4次。在使用redis的过程常见错误总结1.JedisConnectionException Connection Reset参考这边文章:Connection reset原因分析和解决方案https://blog.csdn.net/cwclw/article/details/527971311.1问题描述Exception in thread "main" redis.clients...._jedisconnectionexception: java.net.socketexception: connection reset

Lua5.3版GC机制理解_lua5.3 gc-程序员宅基地

文章浏览阅读8.3k次,点赞8次,收藏42次。目录1.Lua垃圾回收算法原理简述2.Lua垃圾回收中的三种颜色3.Lua垃圾回收详细过程4.步骤源码详解4.1新建对象阶段4.2触发条件4.3 GC函数状态机4.4标记阶段4.5清除阶段5.总结参考资料lua垃圾回收(Garbage Collect)是lua中一个比较重要的部分。由于lua源码版本变迁,目前大多数有关这个方面的文章都还是基于lua5.1版本,有一定的滞后性。因此本文通过参考当前..._lua5.3 gc

手机能打开的表白代码_能远程打开,各种手机电脑进行监控操作,最新黑科技...-程序员宅基地

文章浏览阅读511次。最近家中的潮人,老妈闲着没事干,开始学玩电脑,引起他的各种好奇心。如看看新闻,上上微信或做做其他的事情。但意料之中的是电脑上会莫名出现各种问题?不翼而飞的图标?照片又不见了?文件被删了,卡机或者黑屏,无声音了,等等问题。常常让她束手无策,求助于我,可惜在电话中说不清,往往只能苦等我回家后才能解决,那种开心乐趣一下子消失了。想想,这样也不是办法啊, 于是,我潜心寻找了两款优秀的远程控制软件。两款软件...

成功Ubuntu18.04 ROS melodic安装Cartograhper+Ceres1.13.0,以及错误总结_ros18.04 安装ca-程序员宅基地

文章浏览阅读1.8k次。二.初始化工作空间三.设置下载地址四.下载功能包此处可能会报错,请看:rosdep update遇到ERROR: error loading sources list: The read operation timed out问题_DD᭄ꦿng的博客-程序员宅基地接下来一次安装所有功能包,注意对应ROS版本 五.编译功能包isolated:单独编译各个功能包,每个功能包之间不产生依赖。编译过程时间比较长,可能需要几分钟时间。此处可能会报错:缺少absl依赖包_ros18.04 安装ca

Harbor2.2.1配置(trivy扫描器、镜像签名)_init error: db error: failed to download vulnerabi-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏7次。Haobor2.2.1配置(trivy扫描器、镜像签名)docker-compose下载https://github.com/docker/compose/releases安装cp docker-compose /usr/local/binchmod +x /usr/local/bin/docker-composeharbor下载https://github.com/goharbor/harbor/releases解压tar xf xxx.tgx配置harbor根下建立:mkd_init error: db error: failed to download vulnerability db: database download

推荐文章

热门文章

相关标签