目录
1. 嵌套调用
2. 递归调用
关键点:
- 递归出口:就是递归的结束条件
- 递归式子:递归的表达式
递归是一种常用的手段,但递归程序设计的技巧性要求比较高,有时很难归纳出递归式子。
区分程序书写和程序执行
/* 计算n! */
#include <stdio.h>
double fact(int n); /*函数声明*/
int main()
{
int n;
scanf("%d",&n);
printf("%f",fact(n));/*函数调用*/
return 0;
}
double fact(int n)
{
double result;
if(n == 1 || n == 0){/*递归出口*/
result = 1;
}
else{
result = n * fact(n-1);/*递归式子*/
}
return result;
}
/* 汉诺塔 */
#include <stdio.h>
void hanio(int n, char a, char b, char c);
int main()
{
int n;
printf("input the number of disk:");
scanf("%d",&n);
printf("the steps for %d disk are: \n",n);
hanio(n,'a','b','c');
return 0;
}
void hanio(int n, char a, char b, char c)
{
if(n == 1){
printf("%c-->%c \n",a,b);
}
else{
hanio(n-1,a,c,b);
printf("%c-->%c \n",a,b);
hanio(n-1,c,b,a);
}
}
3 编译预处理指令
所有的编译预处理指令都是在编译预处理步骤中起作用,与程序真正运行过程无关。
3.1 宏定义(#define)
以#开始,表示在编译预处理中起作用,不是真正地C语言,不需要加封号。常用大写字母串作为宏名。宏只是进行替换,宏定义中对变量加上括号,可以保证宏替换的正确性。C语言编写的实用程序中都会有大量的宏定义。
宏的用途:
- 符号常量定义
- 简单的函数功能实现(宏常常限制在一行中)
- 为程序书写带来一些方便。
3.2 文件包含(#include)
3.3 条件编译
如果只想把源程序的一部分语句生成目标代码,可以使用条件编译。#if...#else...#endif。
因为是在编译预处理时起作用,所以#if的条件只能是宏名,不能是程序表达式,因为在编译预处理时是无法计算表达式的。