你该逆袭了
文章目录
- 一、复习函数
- 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;
	else
		min = 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);  // #1
	if (m < 4)       //使递归停止的条件
	{
		digui(m + 1);
	}
	printf("%d 的地址是 %p\n", m, &m);  // #2
	return 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);
	}
	else
		sum = 1;  // 0 的阶乘 是 1  
	              // 0!= 1
	return 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);
	}
	else
		sum = 1;  // 0 的阶乘 是 1  
	              // 0!= 1
	return 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);
	else
		return 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语言小知识点”专栏中,有详细总结。



















