网站 ip pv,百度糯米做网站多少钱,福州做网站费用,什么是php网站1. 先学习/复习C语言的入门知识
1.1 C语言简介
C语言是一种通用的编程语言#xff0c;于1972年由丹尼斯里奇#xff08;Dennis Ritchie#xff09;创建。C语言最初目的是为了开发UNIX操作系统#xff0c;但由于其简洁的语法、快速的执行速度和可移植性#xff0c;自此成…1. 先学习/复习C语言的入门知识
1.1 C语言简介
C语言是一种通用的编程语言于1972年由丹尼斯·里奇Dennis Ritchie创建。C语言最初目的是为了开发UNIX操作系统但由于其简洁的语法、快速的执行速度和可移植性自此成为了一种广泛应用的系统和应用程序开发语言。
1.2 基本数据类型
C语言中的基本数据类型有整数int、浮点数float、double、字符char和布尔bool。下面是一些常用的基本数据类型示例
int num 10; // 整数类型变量
float pi 3.14159; // 单精度浮点数类型变量
double money 1000.5; // 双精度浮点数类型变量
char letter A; // 字符类型变量
bool isTrue true; // 布尔类型变量1.3 变量
在C语言中需要使用变量来存储和操作数据。变量在使用前需要先声明声明变量时需要指定变量的类型。例如
int a; // 定义整数类型变量a
float b; // 定义单精度浮点数类型变量b
double c; // 定义双精度浮点数类型变量c
char d; // 定义字符类型变量d
bool e; // 定义布尔类型变量e在C语言中变量需要初始化后才能使用。可以在声明变量时进行初始化
int a 10; // 定义整数类型变量a并初始化为10
float b 3.14; // 定义单精度浮点数类型变量b并初始化为3.14
char c A; // 定义字符类型变量c并初始化为A
bool d true; // 定义布尔类型变量d并初始化为true1.4 运算符
C语言中常用的运算符包括算术运算符、关系运算符、逻辑运算符和三目运算符等。
算术运算符
int a 10, b 20; // 定义变量a和bint sum a b; // 相加
int diff a - b; // 相减
int mul a * b; // 相乘
int div b / a; // 相除
int mod b % a; // 取模关系运算符
int a 10, b 20; // 定义变量a和bbool isEqual a b; // 是否相等
bool isLess a b; // 是否小于
bool isGreater a b; // 是否大于逻辑运算符
bool isTrue true, isFalse false; // 定义变量isTrue和isFalsebool andResult isTrue isFalse; // 逻辑与
bool orResult isTrue || isFalse; // 逻辑或
bool notResult !isTrue; // 逻辑非三目运算符
int a 10, b 20; // 定义变量a和bint max a b ? a : b; // 如果abmax等于a否则等于b1.5 控制流
C语言中常用的控制流语句包括if语句、for循环、while循环和switch语句等。
if语句
int a 10, b 20; // 定义变量a和bif(a b) { // 如果ab执行以下语句printf(a大于b\n);
} else { // 否则执行以下语句printf(a小于等于b\n);
}for循环
int i; // 声明计数器变量ifor(i 0; i 10; i) { // 循环10次printf(%d\n, i); // 打印当前计数器的值
}while循环
int i 0; // 声明计数器变量iwhile(i 10) { // 循环10次printf(%d\n, i); // 打印当前计数器的值i; // 计数器每次循环自增1
}switch语句
int a 1; // 定义变量aswitch(a) {case 0: // 如果a等于0执行以下语句printf(a等于0\n);break;case 1: // 如果a等于1执行以下语句printf(a等于1\n);break;default: // 如果a不等于0或1执行以下语句printf(其他情况\n);break;
}1.6 函数
C语言中函数是一种独立的代码模块用于完成特定的任务。函数包含函数头和函数体两部分。
函数头包括函数名、返回值类型和参数列表等。例如
int add(int a, int b) { // 定义add函数包含两个整数类型的参数a和b返回值为整数类型int sum a b; // 计算a和b的和return sum; // 返回计算结果
}调用add函数
int result add(10, 20); // 调用add函数将10和20传入
printf(10和20的和为%d\n, result); // 打印结果上面的程序会打印出以下内容
10和20的和为302. 理解函数
在初高中阶段函数通常是指数学函数的概念。
数学函数是一种关系它将一些输入值称为自变量映射到相应的输出值称为因变量。一般这样表示y f(x)。
初高中学习的函数和编程中的函数是有一些相似之处的。在编程中函数用于封装可被重复使用的代码块接收输入和返回输出这和初中学习的函数有些相似之处。
C 语言中的函数是一种可以被重复执行并且可以接收输入和返回输出的代码块。函数可以减少代码的重复性提高程序的可读性和可维护性。
C 语言的函数的格式包括函数名、参数列表、函数体以及返回值。
int add(int x,int y){int a x y;return a;
}函数名add参数列表x、y它们的类型都是int函数体{}大括号里面的内容都是函数体返回值return后面的值是返回值因为add函数前面的int指定了返回值的类型所以这里返回int类型的a。
函数就是输入一些值进行一些操作或处理然后输出一些值
3. 什么是栈
把书或盘子摞起来就像压栈一样需要一次一个地取走它们就像弹栈一样。
栈是一种常见的线性数据结构它遵循后进先出LIFO的原则。栈可以看作是一个容器其中的元素按照后进先出的顺序进行存储和访问。
3.1 后进先出
后进先出Last In First OutLIFO的特性。当数据被插入栈中时它会被放置在栈顶。而当从栈中弹出数据时最后插入栈的数据会首先被弹出。 首先我们向栈中插入元素 A。由于栈是空的插入的元素就变成了栈顶。 然后我们又向栈中插入元素 B。由于栈的特性是后进先出B 就被放在了 A 的上面即成为了栈顶元素。 接下来我们再插入一个元素 C同样的它会被放在栈顶。 当我们从栈中弹出元素时我们会弹出栈顶元素。因此我们先弹出的是 C随后是 B最后是 A。
3.2 入栈和出栈
入栈 和 出栈 是栈的两个基本操作。 入栈Push操作 入栈是将一个新的元素添加到栈的顶部也就是在栈中创建一个新的节点。新元素被放置在栈顶之上并成为新的栈顶元素。 出栈Pop操作 出栈是从栈顶移除一个元素即删除栈顶节点并返回其值。
3.3 类似于栈结构的场景
浏览器的后退和前进每次访问新页面时该页面的信息都会被压入栈中如果用户单击“后退”按钮则最近访问的页面会从栈中弹出以便用户返回上一个页面撤销操作先恢复的最新的状态直到回到所需的状态为止。APP的点击先点击进入商品列表页面然后进入商品详情页面再进入购买页面先返回详情页面再返回商品列表页面。
4. 栈内存和函数调用
4.1 栈内存与栈帧
栈内存Stack Memory是指程序在运行过程中用于存放栈的一段内存空间。栈内存是计算机内存中的一部分通常大小是固定的在程序的运行过程中栈内存会被分成多个栈帧Stack Frame来存放程序需要临时保存的数据比如函数的参数、局部变量、返回地址等等。
每当一个函数或过程被调用时都会创建一个对应的栈帧栈帧会在调用结束后被销毁。
栈帧主要包含以下信息 返回地址Return Address记录了当前函数或过程执行完后程序需要返回到哪个位置继续执行。 参数和局部变量Parameters and Local Variables用于存储函数或过程的输入参数、局部变量的值以及临时变量的空间。 调用者保存的寄存器Caller-Saved Registers保存了在函数调用之前由调用者保存的寄存器的值。 栈指针Stack Pointer记录了当前栈帧的边界即栈顶位置。
4.2 函数调用为什么用到栈
假设A函数调用B函数B函数调用C函数那么函数调用时栈的运作方式如下图所示 当A函数调用B函数时A的状态信息如返回地址、参数等被压入栈中同时分配一块新的栈帧给B函数来保存B的状态信息。当B函数再调用C函数时B的状态信息也会被压入栈中C函数同样会被分配一块新的栈帧来保存C的状态信息。
当C函数执行完毕后控制权回到B函数并弹出C的栈帧恢复到B函数的执行状态。同样当B函数执行完毕后控制权回到A函数并弹出B的栈帧恢复到A函数的执行状态。
函数调用使用栈的主要原因是为了实现函数调用的嵌套和返回的正确性。
当一个函数被调用时它的参数、局部变量以及一些其他信息需要被保存起来以便在函数执行完毕后能够被恢复。这些信息通常保存在函数的栈帧中。同时调用者也需要存储一些信息例如调用该函数前的执行状态以便在函数返回后能够正确恢复。因此调用者的信息也需要保存在栈中。
栈作为一种后进先出LIFOLast-In-First-Out的数据结构非常适合用于保存函数调用相关的信息。每当调用一个函数时会创建一个新的栈帧并将其压入栈中即将栈指针下移。而当函数返回时栈帧就会被弹出即将栈指针上移使得上一个栈帧成为当前栈帧。
5. 函数调用机制
一个简单的C语言代码main函数调用A函数A函数调用B函数B函数调用C函数。
#include stdio.hint C(int z){return z;
}int B(int y){int res C(3);return y res;
}int A(int x){int res B(2);return x res;
}int main(){int a A(1);printf(%d,a);return 0;
}
// 打印结果
// 6①main函数调用A函数传入参数1②A函数调用B函数传入参数2③B函数调用C函数传入参数3④C函数将数值3返回给B函数⑤B函数将2和3相加的结果5返回给A函数①A函数将1和5相加的结果6返回给main函数
在程序运行的时候会创建一个栈内存区域,由于每个函数都有自己的栈帧所以我们可以分别观察每个函数在调用时栈内存的变化。 ebp寄存器在函数调用和返回过程中起到重要的作用主要有以下几个方面的功能 函数调用时ebp用于保存调用者函数的栈帧指针。当一个函数被调用时它会在栈上分配一个新的栈帧来保存该函数的局部变量、参数和其他必要的信息。将调用者函数的ebp保存在当前函数的栈帧中可以在当前函数执行完毕后恢复调用者函数的上下文。 在函数执行期间ebp用于定位栈上的局部变量和函数参数。通过ebp函数可以通过相对于EBP的偏移来访问其参数和局部变量而不受栈帧的变化影响。这样可以在函数中方便地引用和修改局部变量和参数。 函数返回时ebp用于恢复调用者函数的栈帧指针和上下文。当一个函数执行完毕后它会从栈上弹出自己的栈帧并恢复调用者函数的栈帧指针即调用者函数的ebp。这样就可以在返回后继续执行调用者函数的代码而不会导致栈帧混乱。
6. 总结
本文首先介绍了C语言的基本概念包括数据类型、变量、表达式、流程控制语句等从而为后续学习打下基础。在此基础上我们阐述了函数调用机制深入探讨了栈、栈内存和栈帧等概念从而使读者能够全面了解函数调用的过程和栈帧的作用。
关注微信公众号“小虎哥的技术博客”让我们一起成为更优秀的程序员❤️
文章和代码仓库
gitee(推荐)https://gitee.com/cunzaizhe/xiaohuge-blog
githubhttps://github.com/tigerleeli/xiaohuge-blog