你该逆袭了
文章目录
- 一、复习函数
- 1、定义带形式参数的函数
- 2、声明带形式参数函数的原型
- 3、使用 return 从函数中返回值
- (1)、返回值不仅可以赋给变量,也可以被用作表达式的一部分。
- (2)、返回值不一定是变量的值,也可以是任意表达式的值。
- (3)、如果函数返回值的类型与函数声明的类型不匹配怎样?
- (4)、return 用来终止函数并把控制返回给主调函数的下一条语句。
- return; 的作用
- 4、函数类型
- (1)函数声明既可以在主调函数外面,也可以放在主调函数里面。
- 二、ANSI C 函数原型
- 1、无参数和未指定参数
- 2、函数原型的优点
- 三、递归
- 1、演示递归
- 2、递归的基本原理
- 3、尾递归
- 4、递归和倒序计算
- 5、递归的优缺点
- 四、编译多源代码文件的程序
- 1、使用头文件
- (1)示例程序的注意点
- (2)示例程序
- (3)示例程序的运行结果截图
- 五、查找地址:&运算符
一、复习函数
1、定义带形式参数的函数
void dibs(x, y, z)
char x, y, z;void dibss(x, y) //这里,圆括号中只有参数列表,而参数的类型在后面声明。
int x;
char y;//这是 ANSI C 之前的形式,现在已经将其废弃不用
2、声明带形式参数函数的原型
3、使用 return 从函数中返回值
#include <stdio.h>int imin(int, int);int main()
{int num1 = 0; int num2 = 0;printf("enter a pair of integers (q to quit):\n");while (scanf("%d %d", &num1, &num2) == 2){printf("the lesser of %d and %d is %d.\n",num1, num2, imin(num1, num2));printf("enter a pair of integers (q to quit):\n");}printf("bye\n");return 0;
}int imin(int n, int m)
{int min = 0;if (n < m)min = n;elsemin = m;return min;
}
(1)、返回值不仅可以赋给变量,也可以被用作表达式的一部分。
answer = 2 * imin(z, zstar) + 25;
printf("%d\n", imin(-32 + answer, LIMIT));
(2)、返回值不一定是变量的值,也可以是任意表达式的值。
imin(int n, int m)
{return (n < m) ? n : m;
}
(3)、如果函数返回值的类型与函数声明的类型不匹配怎样?
(4)、return 用来终止函数并把控制返回给主调函数的下一条语句。
return; 的作用
4、函数类型
声明函数时必须声明函数的类型。带返回值的函数类型应该与其返回值类型相同,而没有返回值的函数应声明为 void。
(1)函数声明既可以在主调函数外面,也可以放在主调函数里面。
二、ANSI C 函数原型
1、无参数和未指定参数
2、函数原型的优点
三、递归
结束递归 是使用递归的难点,因为如果递归代码中没有终止递归的条件测试部分,一个调用自己的函数会无限递归。
1、演示递归
如果函数使用%p转换说明打印地址,如果你的系统不支持这种格式,请使用 %u 或者 %lu 代替 %p。
#include <stdio.h>void digui(int n);int main()
{digui(1);return 0;
}void digui(int m)
{printf("%d 的地址是 %p\n", m, &m); // #1if (m < 4) //使递归停止的条件{digui(m + 1);}printf("%d 的地址是 %p\n", m, &m); // #2return 0;
}
2、递归的基本原理
(1)每级函数调用都有自己的变量。
(2)每次函数调用都会返回一次。当函数执行完毕后,控制权将被传回上一级递归。且程序必须按顺序逐级返回递归。
(3)递归函数中位于 递归调用之前 的语句,均按被调函数的顺序执行。
(4)递归函数中位于 递归调用之后 的语句,均按被调函数相反的顺序执行。
(5)虽然每级递归都有自己的变量,但是并没有拷贝函数的代码。
(6)递归函数必须包含能让递归调用停止的语句。
3、尾递归
最简单的递归形式是把递归调用置于函数的末尾,即正好在 return 语句之前。这种形式的递归被称为 尾递归,因为递归调用在函数的末尾。
分别用 循环 和 递归 计算阶乘:
#include <stdio.h>long recur(int x); //阶乘
long xunhuan(int x); //循环int main()
{int input = 0;printf("请输入 12 以内的正整数(q to exit)\n");while ((scanf("%d", &input) == 1)){if (input > 12){printf("请输入12以内的整数,你输入的数据太大。\n");}else if (input < 0){printf("你输入的数据是负数,请重新输入数据。\n");}else{printf("递归:%d 的阶乘是 %d\n", input, recur(input));printf("循环:%d 的阶乘是 %d\n", input, xunhuan(input));}}printf("bye\n");return 0;
}long recur(int x)
{long sum = 0;if (x > 0){sum = x * recur(x - 1);}elsesum = 1; // 0 的阶乘 是 1 // 0!= 1return sum;
}long xunhuan(int x)
{long sum = 1;for (sum = 1; x >= 1; x--){sum *= x;}return sum;
}
代码的关键点:
虽然递归调用不是函数的最后一行,但是当 x > 0 时,它是该函数执行的最后一条语句,因此它也是 尾递归。
long recur(int x)
{long sum = 0;if (x > 0){sum = x * recur(x - 1);}elsesum = 1; // 0 的阶乘 是 1 // 0!= 1return sum;
}
4、递归和倒序计算
用二进制形式打印整数
#include <stdio.h> void binary(int n);int main()
{int input = 0;printf("请输入一个整数:\n");while (scanf("%d", &input) == 1){printf("以二进制的形式输出:");binary(input);putchar('\n');printf("请继续输入整数,q to exit\n");}printf("bye\n");return 0;
}void binary(int n)
{int r = 0;r = n % 2;if (n >= 2){binary(n / 2);}putchar(r == 0 ? '0' : '1'); //此处注意,输出 字符‘1’ 和 字符‘0’return; //什么也不返回
}
注意点:
putchar(r == 0 ? '0' : '1');
//此处注意,输出 字符‘1’ 和 字符‘0’return; //什么也不返回
5、递归的优缺点
优点:
递归为编程问题提供了最简单的解决方案。
缺点:
一些递归算法会快速消耗计算机的内存资源。
(举例:Fibonacci函数)
#include <stdio.h>int fibonacci(int);int main()
{int input = 0;printf("请输入整数:");scanf("%d", &input);fibonacci(input);printf("%d\n", fibonacci(input));return 0;
}int fibonacci(int n)
{if (n > 2)return fibonacci(n - 1) + fibonacci(n - 2);elsereturn 1;
}
四、编译多源代码文件的程序
1、使用头文件
(1)示例程序的注意点
以下程序注意点:
scanf("%*s");
处理非数值输入,跳至下一个空白字符。
(2)示例程序
usehotel.c ————房间费率程序
#include <stdio.h>
#include "hotel.h" //定义符号常量,声明函数int main()
{int nights;double hotel_rate;int code;while ((code = menu()) != QUIT){switch (code){case 1: hotel_rate = HOTEL1;break;case 2: hotel_rate = HOTEL2;break;case 3: hotel_rate = HOTEL3;break;case 4: hotel_rate = HOTEL4;break;default:hotel_rate = 0.0;printf("oops!\n");break;}nights = getnights();showprice(hotel_rate, nights);}printf("thank you and goodbye.\n");return 0;
}
hotel.c ————酒店管理函数
#include <stdio.h>
#include "hotel.h"int menu(void)
{int code, status;printf("\n%s%s\n", STARS, STARS);printf("enter the number of the desired hotel:\n");printf("1) Fairfield Arms 2) Hotel olympic\n");printf("2) chertworthy plaza 4) the stockton\n");printf("5) quit\n");printf("%s%s\n", STARS, STARS);while ((status = scanf("%d", &code)) != 1 ||(code < 1 || code>5)){if (status != 1){scanf("%*s"); //处理非整数输入}printf("enter an integer from 1 to 5,please.\n");}return code;
}int getnights(void)
{int nights;printf("how many nights are needed? ");while (scanf("%d", &nights) != 1){scanf("%*s"); //处理非整数输入printf("please enter an integer ,such as 2.\n");}return nights;
}void showprice(double rate, int nights)
{int n;double total = 0.0;double factor = 1.0;for (n = 1; n < nights; n++, factor *= DISCOUNT)total += rate * factor;printf("the total cost will be $%0.0f.\n", total);
}
hotel.h ————符号常量 和 hotel.c 中所有函数的原型
//符号常量 和 hotel.c 中所有函数的原型#define QUIT 5
#define HOTEL1 180.00
#define HOTEL2 225.00
#define HOTEL3 255.00
#define HOTEL4 355.00
#define DISCOUNT 0.95
#define STARS "***********************************"//显示选择列表
int menu(void);//返回预定天数
int getnights(void);//根据费率,入住天数计算费用
//并显示结果
void showprice(double rate, int nights);
(3)示例程序的运行结果截图
五、查找地址:&运算符
主调函数不使用 return 返回的值,则必须通过地址才能修改主调函数中的值。
#include <stdio.h>int main()
{int a = 0;int b = 9;printf("a=%d &a=%p\n", a, &a);printf("a=%d &a=%p\n", b, &b);acc(a);return 0;
}int acc(int a)
{int b = 10;printf("a=%d &a=%p\n", a, &a);printf("a=%d &a=%p\n", b, &b);
}
总结:
从所得地址可以看出,这是 4 个不同的独立变量。
仅仅只是实现了值传递。
其余是指针的概念,在我的“C语言小知识点”专栏中,有详细总结。