c语言进阶(1)

简介: c语言进阶(1)

文本代码->可执行文件->通过双击可以执行该程序

生成可执行程序并运行程序

双击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......一起学习进步!

相关文章
|
6月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
6月前
|
数据库 C语言
C语言进阶 文件操作知识(上)
C语言进阶 文件操作知识(上)
41 3
|
6月前
|
存储 C语言
C语言进阶 文件操作知识(下)
C语言进阶 文件操作知识(下)
40 2
|
6月前
|
存储 编译器 数据库
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
|
7月前
|
编译器 C语言 C++
从C语言到C++_21(模板进阶+array)+相关笔试题(下)
从C语言到C++_21(模板进阶+array)+相关笔试题
49 2
|
7月前
|
C语言
C语言进阶:进阶指针(下)
C语言进阶:进阶指针(下)
51 2
|
6月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
52 0
|
7月前
|
C语言
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(二)
我们可以通过创建并定义符号常量NUMBER,来作为判断是否胜利的标准。如三子棋中,令NUMBER为3,则这八个方向中有任意一个方向达成3子连珠,则连珠的这个棋子所代表的玩家获胜。
79 1
|
7月前
|
算法 C语言 C++
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(一)
三子棋游戏设计的核心是对二维数组的把握和运用。
93 1
|
7月前
|
C语言
C语言进阶:指针的进阶(上)
C语言进阶:指针的进阶(上)
66 1