目录
函数栈帧的函数创建和销毁::
解决问题:
1.局部变量是怎么创建的?
2.为什么局部变量的值是随机值?
3.函数是怎么传参的?
4.形参和实参是什么关系?
5.函数调用结束后怎么返回的?
C语言编程训练
1.编写程序将三个整数从大到小输出
2.编写程序打印1—100之间所有3的倍数的数字
3.编写程序求两个数的最大公约数
4.编写程序计算1/1-1/2+1/3-1/4+1/5+......+1/99-1/100
5.求十个整数中最大值
6.打印九九乘法口诀表
7.实现一个函数来打印乘法口诀表,行数列数自己指定
函数栈帧的栈帧创建和销毁::
ebp,esp这两个寄存器中存放的建和是地址,这两个地址是销毁用来维护函数栈帧的,edp被称为栈底指针,函数esp被称为栈顶指针。栈帧push:压栈:给栈顶放一个元素。建和pop:出栈:给栈顶删一个元素,销毁lea:加载有效地址。函数dword=4byte。栈帧
int Add(int x,建和int y){ push ebp mov ebp,esp push ebx push esi push edi lea edi [ebp+FFFFFF34h] mov ecx,33h mov eax,0CCCCCCCh rep stos dword ptres:[edi]int z = 0; mov dword ptr[ebp-8] 0z = x + y; mov eax,dword ptr [ebp+8] add eax,dword ptr [ebp+0Ch] mov dword ptr [ebp-8] eax mov eax,dword ptr [ebp-8] pop edi pop esi pop ebx mov ebp,esp pop ebp ret}
int main(){ push ebp mov ebp,esp sub esp,0E4h push ebx push esi push edi lea edi,[ebp-0E4h] mov ecx,39h mov eax,0ccccccch rep stos dword ptr es:[edi]int a = 10; mov dword ptr[ebp-8],0Ahint b = 20; mov dword ptr[ebp-14h],14hint c = 0; mov dword ptr[ebp-20h],0c = Add(a,b); mov eax,dword ptr [ebp-14h] push eax mov ecx,dword ptr [ebp-8] push ecx call 00C210E1 add esp,8 00C21450 mov dword ptr[ebp-20h],eaxprintf("%d\n",c); mov esi,esp mov eax,dword ptr[ebp-20h] push eax push 0C25858h call dword ptr ds:[00C29114] add esp,8 cmp esi,esp cabl 00C2133Breturn 0;}
解决问题:
1.局部变量是怎么创建的?
答:首先为此次函数调用创建函数栈帧,在函数栈帧找空间存放局部变量值。销毁
2.为什么局部变量的函数值是随机值?
随机值是系统开辟完函数栈帧后系统随机放进去的。
3.函数是栈帧怎么传参的?
形参在刚开始调用之前就已经传过去了,形式参数从左向右传递。建和
4.形参和实参是什么关系?
形参是实参的临时拷贝,值相同但空间不同,因此改变形参的值不会影响实参的值。
5.函数调用结束后怎么返回的?
返回值并不会随着函数作用域的销毁而销毁,而是放在eax中准备返回,当通过pop出栈回到main函数中再将返回值放到局部变量中。
C语言编程训练
1.编写程序将三个整数从大到小输出
#include代码1 int main() { int a = 0; int b = 0; int c = 0; int temp = 0; scanf("%d %d %d", &a, &b, &c); if (a < b) { temp = a; a= b; b = temp; } if (a < c) { temp = a; a = c; c = temp; } if (b < c) { temp = b; b = c; c = temp; } printf("%d %d %d", a, b, c); return 0; }代码2:函数版Swap(int* px, int* py){ int temp = *px; *px = *py; *py = temp;}int main(){ int a = 0; int b = 0; int c = 0; scanf("%d %d %d", &a, &b, &c); if (a < b) { Swap(&a, &b); } if (a < c) { Swap(&a, &c); } if (b < c) { Swap(&b, &c); } printf("%d %d %d", a, b, c); return 0;}
2.编写程序打印1—100之间所有3的倍数的数字
#include打印1-100之间所有3的倍数的数字代码1int main(){ int i = 0; for (i = 1; i <= 100; i++) { if (i % 3 == 0) printf("%d ", i); } return 0;} 代码2int main(){ int i = 0; for (i = 3; i <= 100; i += 3) { printf("%d ", i); } return 0;}
3.编写程序求两个数的最大公约数
#include求两个数的最大公约数 代码1int main(){ int a = 0; int b = 0; scanf("%d %d", &a, &b); int min = (a < b ? a : b); int m = min; while (1) { if (a % m == 0 & b % m == 0) { break; } m--; } printf("%d\n", m); return 0;}代码2辗转相除法:24 % 18 == 6 18 % 6 == 0int main(){ int a = 0; int b = 0; scanf("%d %d", &a, &b); while (a % b) { int c = a % b; a = b; b = c; } printf("%d\n", b); return 0;}优化int main(){ int a = 0; int b = 0; int c = 0; scanf("%d %d", &a, &b); while (c = a % b) { a = b; b = c; } return 0;}
4.编写程序计算1/1-1/2+1/3-1/4+1/5+......+1/99-1/100
#includeint main(){ int i = 0; double sum = 0.0; int flag = 1; for (i = 1; i <= 100; i++) { sum = sum + flag*(1.0 / i);//一定不能写成1/i flag = -flag;//不能写成flag=-1 } printf("%lf\n", sum); return 0;}
5.求十个整数中最大值
#include代码1int main(){ //准备10个整数 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; //找出最大值 int i = 0; int max = arr[0];//max不能赋值成0来比较负数 for (i = 1; i < 10; i++) { if (arr[i] >max) { max = arr[i]; } } printf("%d\n",max); return 0;}代码2int main(){ int arr[10] = { 0}; //输入数字 int n = 0; for(n = 0;n < 10;n++){ scanf("%d",&arr[n]);} //找出最大值 int i = 0; int max = arr[0];//max不能赋值成0来比较负数 for (i = 1; i < 10; i++) { if (arr[i] >max) { max = arr[i]; } } printf("%d\n",max); return 0;}
6.打印九九乘法口诀表
#include代码1int main(){ int i = 0; for (i = 1; i <= 9; i++) { int j = 0; for (j = 1; j <= i; j++) { printf("%d*%d=%-2d ", i,j, i * j); } printf("\n"); } return 0;}代码2int main(){ int i = 0; for (i = 1; i <= 9; i++) { int j = 0; for (j = 1; j <= i; j++) { printf("%d*%d=%-2d ", j,i, i * j); } printf("\n"); } return 0;}
补:编写程序打印1到100之间数字9出现的个数
#includeint main(){ int i = 0; int count = 0;//计数 for (i = 1; i <= 100; i++) { if (i % 10 == 9)//判断个位是不是9 count++; if (i / 10 == 9)//判断十位是不是9 count++; } printf("count=%d\n", count); return 0;}
7.实现一个函数来打印乘法口诀表,行数列数自己指定
#includevoid print_table(int n){ int i = 0; for (i = 1; i <= n; i++) { int j = 0; for (j = 1; j <= i; j++) { printf("%d*%d=%-2d ", j, i, i * j); } printf("\n"); }}int main(){ int n = 0; scanf("%d", &n); print_table(n); return 0;}