函数:
函数调用的关系:调用者与被调用者。
int main(void)
{
primtf("%d\n",add());
return 0;
}
这个里面:main是调用者,main是整个函数的入口,只能是调用者,add在此处是被调用者,add函数里面也可以调用其他函数。
C语言把程序划分了5个区域:
1.栈:主要用来存放自动变量或函数调用的数据。
2.堆:空间大,但要使用它的空间时,需要手动申请。
3.字符串常量区:里面存放的字符为只读权限。
4.静态区(全局区):存放全局变量和静态变量。
5.代码区:存放的代码为只读。
程序 = 代码(存放于5)+数据(存放在1~4)
栈:一种数据结构(表示数组组织形式)
特点:先进后出。
C语言角度的栈:
1.本质上是一块内存空间
2.只是按照栈这种数据来处理和使用的。
函数调用的本质:实际上是利用栈的结构--先进后出,保证了函数可以层层嵌套调用栈帧。
程序从main函数进入执行到调用函数,则进入被调用函数里面执行,那么执行完被调用函数后程序怎么知道回到哪里继续执行呢?
这要归功于program counter ---程序计数器:
它保存现场,即相当于看电视保存进度,保存好调用函数之前的进度,执行到哪里,回来之后就从哪里开始继续执行程序。
递归:即函数调用自己;
1 #include <stdio.h>
2
3 void func1(void)
4 {
5 printf("--------hello--------\n");
6 func1();
7 }
8 int main()
9 {
10 func1();
11 return 0;
12 }
相当于死循环,但是循环一会后会出现报错segmentation fault ,即栈溢出。
原因:调用函数即压栈,一直调用一直压栈,最后栈满后就没有栈空间调用printf函数,所以报错。
递归求前n项和:
1 #include <stdio.h>
2
3 int sum(int n)
4 {
5 if(n == 1)
6 {
7 return 1;
8 }
9 else
10 {
11 return n +sum(n-1);
12 }
13 }
递归求n的阶乘:
int factorial(int n)
{
if(n == 1)
{
return 1;
}
else
{
return n*factorial(n-1);
}
}
递归求斐波拉契数列前n项和:
1 #include <stdio.h>
2
3 int fabolaqi_N(int i)
4 {
5 if(i == 0||i == 1)
6 {
7 return 1;
8 }
9 else
10 {
11 return fabolaqi_N(i-1)+fabolaqi_N(i-2);
12 }
13 }
14
15 int fabolaqiSum(int n)
16 {
17 int sum = 0;
18 for(int i = 0;i < n;i++)
19 {
20 sum += fabolaqi_N(i);
21 }
22 return sum;
23 }
24
25 int main()
26 {
27 int n,ret;
28 scanf("%d",&n);
29 ret = fabolaqiSum(n);
30 printf("sum = %d\n",ret);
31
32 }
~
函数包装求双胞胎素数(即前一个素数与后一个素数的差为2):
1 #include <stdio.h>
2
3 int isPrime(int i)
4 {
5 int j;
6 int flag = 1;
7 for(j = 2;j <i;j++)
8 {
9 if(i%j == 0)
10 {
11 return 0;
12 break;
13 }
14 }
15 return flag;
16
17 }
18 void doublePrime(int n)
19 {
20 for(int i = 2;i <= n-2;i++)
21 {
22 if(isPrime(i) && isPrime(i+2))
23 {
24 printf("%d %d\n",i,i+2);
25 }
26 }
27 }
28 int main()
29 {
30 int n;
31 printf("input n:");
32 scanf("%d",&n);
33 doublePrime(n);
34 return 0;
35 }