[C语言]函数栈帧的创建和销毁

目录 

函数栈帧的创建和销毁::

                解决问题:

                  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.实现一个函数来打印乘法口诀表,行数列数自己指定


函数栈帧的创建和销毁::

知识铺垫:

 为了观察函数栈帧的创建和销毁,我们这里采用最简单的代码,并将其做了详细的拆分。

#include  
int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}
int main()
{
	int a = 10;
	int b = 20;
	int c = 0;
	c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

有关寄存器的知识铺垫:

寄存器有很多像eax,ebx,ecx,edx,那么聊函数栈帧就要搞懂ebp,esp这两个寄存器,ebp,esp存放的是地址,这两个寄存器是用来维护函数栈帧的。

我们知道每调用一个函数,都要在栈区上为它分配空间。

对于上面的一段代码——

[C语言]函数栈帧的创建和销毁_第1张图片 main函数的汇编代码:

[C语言]函数栈帧的创建和销毁_第2张图片

 Add函数的汇编代码:

[C语言]函数栈帧的创建和销毁_第3张图片

函数栈帧建立的详细过程:

[C语言]函数栈帧的创建和销毁_第4张图片

解决问题:

1.局部变量是怎么创建的?

答:首先为此次函数调用创建函数栈帧,在函数栈帧找空间存放局部变量值。

2.为什么局部变量的值是随机值?

随机值是系统开辟完函数栈帧后系统随机放进去的。

3.函数是怎么传参的?

形参在刚开始调用之前就已经传过去了,形式参数从左向右传递。

4.形参和实参是什么关系?

形参是实参的临时拷贝,值相同但空间不同,因此改变形参的值不会影响实参的值。

5.函数调用结束后怎么返回的?

返回值并不会随着函数作用域的销毁而销毁,而是放在eax中准备返回,当通过pop出栈回到main函数中再将返回值放到局部变量中。

C语言编程训练

1.编写程序将三个整数从大到小输出

[C语言]函数栈帧的创建和销毁_第5张图片

#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\n", 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\n", a, b, c);
	return 0;
}

[C语言]函数栈帧的创建和销毁_第6张图片  

2.编写程序打印1—100之间所有3的倍数的数字

#include
//打印1-100之间所有3的倍数的数字
//代码1
int main()
{
	int i = 0;
	for (i = 1; i <= 100; i++)
	{
		if (i % 3 == 0)
			printf("%d ", i);
	}
	return 0;
}
//代码2
int main()
{
  int i = 0;
	for (i = 3; i <= 100; i += 3)
	{
		printf("%d ", i);
	}
	return 0;
}

[C语言]函数栈帧的创建和销毁_第7张图片3.编写程序求两个数的最大公约数

[C语言]函数栈帧的创建和销毁_第8张图片

#include 
//求两个数的最大公约数
//代码1
int 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 == 0
int 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;
}

[C语言]函数栈帧的创建和销毁_第9张图片

4.编写程序计算1/1-1/2+1/3-1/4+1/5+......+1/99-1/100

#include
int 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;
}

[C语言]函数栈帧的创建和销毁_第10张图片

5.求十个整数中最大值

   

#include
//代码1
int 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;
}
//代码2
int 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;
}

[C语言]函数栈帧的创建和销毁_第11张图片6.打印九九乘法口诀表

  

#include
int main()
{
	int i = 1;
	for (i = 1; i <= 9; i++)
	{
		int j = 0;
		for (j = 1; j <= i; j++)
		{
			printf("%d*%d=%d\t", j, i, i * j);
		}
		printf("\n");
	}
	return 0;
}

[C语言]函数栈帧的创建和销毁_第12张图片补:编写程序打印1到100之间数字9出现的个数

[C语言]函数栈帧的创建和销毁_第13张图片  

#include
int 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;
}

[C语言]函数栈帧的创建和销毁_第14张图片 

7.实现一个函数来打印乘法口诀表,行数列数自己指定

#include
void 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;
}

[C语言]函数栈帧的创建和销毁_第15张图片

你可能感兴趣的:(开发语言,c语言,c++)