文本代码->可执行文件->通过双击可以执行该程序
生成可执行程序并运行程序
双击link的世界
双击是程序在干什么?将程序数据加载到内存当中,让计算机运行。任何程序在运行之前,都必须被加载到内存当中。
接着让我们思考两个问题:1.为什么程序运行之前都要被加载到内存当中?快
2.在程序被加载到内存之前,程序在哪里?在硬盘当中。
有关变量
什么是变量?在内存中(在程序运行时)开辟特定大小的空间,用来保存数据。所有的变量本质上都是要在内存的某个位置上开辟空间的。
为什么要定义变量?计算机就是为了计算的,而计算需要数据,而任何一个时刻,不是所以数据都要被计算。因为有数据要暂时被保存起来,等待后续处理。
定义与声明
定义:就是在内存中开辟特定大小的空间(只能有一次)
声明:告知,关联(可多次)
关键字
auto(局部变量默认)
变量分为局部变量和全局变量。局部变量就是在代码块内定义的,而全局变量是在代码块内定义的,全局变量具有全局性。
作用域更多描述的是作用范围(改变量的有效范围),生命周期描述的是时间的概念,什么时候被声明,什么时候被释放。那么,是在任何地方都可以被使用吗?并不是。
register
计算机里具有存储能力的硬件:CPU:寄存器,cache,内存,硬盘/ssd/flash。离CPU越近的存储单元,效率越高,单价越贵。CPU是用来访问内存的。把硬盘的内容存到内存上,本质上就是一种缓存技术。
任何一种硬件而言,都充当着上游硬件的缓存。
CPU访问数据时,以最小的成本达到最高的效率。
寄存器存在的本质:在硬件层面上,提高计算器的运行效率,因为不需要从内存中读取数据。
那么什么样的变量,能够被register修饰呢?
1.局部的(如果是全局,会导致cpu中长时间占存)
2.不会被写入的(写入就要写回内存,后续还要检测的话,register就体现不出它的意义)
写入是什么意思?比如我们定义一个变量i,这个变量i就在内存上被开辟了。如果我们要进行i++,就必须把i的值读到CPU当中的寄存器里。变量修改完成后,我们需要将修改后的变量写会内存当中。
3.高频被使用的
4.如果使用,不要大量使用,因为寄存器数量有限
regsiter修饰的变量不需要在内存当中开辟,这个变量一般没有地址,就不能对其取地址。尽量将所修饰变量,放进CPU寄存器当中,从而提高效率。
程序在运行之前,必须先加载到内存当中。我们必须把要处理的数据临时保存起来。
static
.h:头文件。组织项目结构的时候,减少大型项目的维护。
为什么要有头文件呢?单纯地使用源文件,组织项目结构的时候,项目越大越复杂的时候,维护成本会变得越来越高。
头文件一定是会被多个源文件包含的。头文件可能会被重复包含,为了保证头文件不被重复包含,我们有两种写法:
1.在开头写上#pragma once
头文件里会包含哪些内容呢?
使用尖括号包含的是c语言的头文件,包含自定义用双引号。
那么在下面这个函数中,为什么show()函数未定义,程序还是能够运行成功呢?
printf是包含在库函数里的,那我们是什么时候去找printf的定义和实现的呢?是在程序最后一步实现可执行链接的时候。在函数调用的地方,一般都是以某种符号的形式存在的,当在最后一步链接的时候,我们找不到这个函数,才会报错。编译时不存在,编译器会以告警的形式提示。但是在text.c的.o文件当中又找到了这个函数。函数的声明本质上也是在内存上开辟空间,只不过变量保存的是数据,而函数保存的是代码,这个代码保存好之后一般是不可被写入的。只要是声明,可以也给extern带上(建议)。这是因为函数是定义还是声明,编译器取决于它有没有函数体,编译器如果识别到没有函数体,就被解释成了声明。变量声明必须把extern带上。如果只是单纯的int a;这个语句,编译器有可能把它认为是定义,而头文件当中并不包含,应该包含extern声明。
如果一个函数没有参数,但是我们给它传一个参数,竟然不会报错。
1.全局变量可以跨文件访问吗?可以。
2.函数可以跨文件访问吗?可以。
为什么呢?大型项目一定是多文件的,多个文件之间一定要进行数据交互。如果不能跨文件,交互成本比较高。
在具体的应用场景当中,我们有可能只想在某一个特定的函数内部使用,而不想在其他函数内部使用
结论:1.static修饰全局变量,该变量只在本文件内被访问,不能被外部其他文件直接访问
2.static修饰函数,该函数只在本文件内被访问,不能被外部其他文件直接访问
3.static修饰局部变量,更改该局部变量的生命周期(将临时变量改为全局生命周期),作用域不变
全局变量和函数一旦被static修饰只能被同名的自身文件内被访问,不能够被外界访问(但不是严格意义来说),但是可以通过嵌套的方式进行调用的。
static是项目维护和提供安全保证的关键字。static修饰限制的是作用域。
接下来,我们讨论static修饰局部变量。那么下面这个函数有什么结果呢?
打印的结果应该是10个1。这是因为i是局部变量,具有临时性,函数调用开辟空间并初始化,函数结束释放空间。这个i不断被初始化为0。i的地址不断变化。
如果我们给局部变量加上static修饰,会怎么样呢?结果变成了1到10。
拿i为4为例,它要自增到4,那么它的前一个值一定不能为0。i在运行的过程中,并没有被释放。
打印出的结果为100,换而言之,a变量并没有被释放掉。
那么为什么临时变量具有临时性,全局变量具有全局性呢?
欢迎交流!后续将会出2,3,4......一起学习进步!