学习目标:
掌握多参数、单返回值的数学函数的定义和使用方法
学会用typedef定义结构体
学会用assert宏帮助调试
理解函数调用时用实参给形参赋值的过程
学会定义局部变量和全局变量
理解调用栈和栈帧,学会用gdb查看调用栈并选择栈帧
理解地址和指针
理解递归定义和递归函数
理解可执行文件中的正文段、数据段和BSS段/*
BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。
熟悉堆栈段,了解栈溢出的常见原因
4-1 组合数
输入非负整数m和n,输出组合数C(m,n)=n!/(m!*(n-m)!),其中m≤n≤20.
代码:
#include<stdio.h> int f(int n) { int i,m=1; for(i=1;i<=n;i++) m*=i; return m; } int main() { int m,n; scanf("%d %d",&m,&n); printf("%d\n",f(n)/f(m)*f(n-m)); return 0; }
4-2 孪生素数
如果n和n+2都是素数,则称它们是孪生素数。输入m,输出两个数均不超过m的最大孪生素数。5≤m≤10000.例如m=20时的答案是17、19,m=1000时答案是881、883.
代码:
#include<stdio.h> #include<math.h> #include<assert.h>//限制非法函数调用 int is_prime(int x)//is it a prime? { int i,m;//m避免重复计算sqrt(x),通过四舍五入避免浮点误差 assert(x>=0); if(x==1) return 0; m=floor(sqrt(x)+0.5); for(i=2;i<=m;i++) if(x%i==0) return 0; return 1; } int main() { int i,m; scanf("%d",&m); for(int i=m-2;i>=3;i--) if(is_prime(i)&&is_prime(i+2)) { printf("%d %d\n",i,i+2); break; } return 0; }
4-5 用函数交换变量
需用到指针和栈 否则不能成功调用交换函数
代码:
#include<stdio.h> void swap(int* a,int* b) { int t=*a; *a=*b; *b=t; } int main() { int a=3,b=4; swap(&a,&b);//&才改变了实参的值 printf("%d %d\n",a,b); return 0; }
4-6用递归法计算阶乘
数学函数也可以递归定义:阶乘函数f(n)=n!可以定义为:{ f(0)=1
f(n)=f(n-1)*n(n≥1)
代码:
#include<stdio.h> int f(int n) { return n==0?1:f(n-1)*n;//学会运用 十分方便的方法 } int main() { printf("%d\n",f(3)); return 0; }