【函数的嵌套调用和链式访问】
【嵌套调用】:
#include <stdio.h> void new_line() { printf("hehe\n"); } void three_line() { int i = 0; for(i=0; i<3; i++) { new_line(); } } int main() { three_line(); return 0; }
以上这样函数之间可以相互调用。
注意:函数可以嵌套调用但是不能嵌套定义。
嵌套定义的例子:
#include <stdio.h> void three_line() { void new_line()//不能在函数中再次定义函数。会编译出错 { printf("hehe\n"); } int i = 0; for(i=0; i<3; i++) { new_line(); } } int main() { three_line(); return 0; }
【链式访问】
链式访问就是将一个函数的返回值作为另外一个函数的参数。
例子:
#include <stdio.h> #include <string.h> int main() { char arr[20] = "hello"; int ret = strlen(arr); printf("%d\n", ret); return 0; }
上段代码中,strlen函数将字符串arr的长度计算出之后,将结果赋值给了ret变量,再通过printf函数打印ret变量展示计算结果。
我们将这段代码改进以下:
#include <stdio.h> #include <string.h> int main() { char arr[20] = "hello"; printf("%d\n", strlen(arr)); return 0; }
改进之后,strlen函数将返回值直接作为printf函数的参数并进行打印操作,这就是函数的链式访问。
【链式访问的小练习】:
int main() { printf("%d", printf("%d", printf("%d", 43))); //结果是啥? //打印4321 return 0; }
要想知道执行结果,就必须知道printf函数的返回值的含义:
通过查阅,printf函数的返回值就是被打印的字符的个数,那么就可以推测打印结果了。最里面的printf函数打印了43,返回值是2,外一层的printf函数再将2打印,返回1,最外层的printf函数再将1打印。
那么下面这段代码的结果呢?
int main() { printf("%d", printf("%d", printf("%d ", 43)));//这里多了一个空格 //结果是啥? return 0; }
【函数递归】
程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接 调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问 题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程 序的代码量。递归主要思想是将大事化小。
举个例子:
int main()//这就是递归,当然这是个错误的示范。 { printf("hello\n"); main(); }
练习1:写一个能打印一个整数的每一位的递归
void print(unsigned int n) { if (n > 9) { print(n/10); } printf("%d ", n % 10); } int main() { unsigned int num = 0; scanf("%d", &num);//1234 print(num); return 0; }
运行结果:
图解:
递归的必要条件:
- 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
- 每次递归调用之后越来越接近这个限制条件。
练习2:写一个能求字符串函数的递归函数
#incude <stdio.h> int Strlen(const char*str) { if(*str == '\0') return 0; else return 1+Strlen(str+1); } int main() { char *p = "abcdef"; int len = Strlen(p); printf("%d\n", len); return 0; }
练习
实现可以判断一个数是不是素数的函数。
int IsPrime(int n)//100 - 200的素数 { int i = 0; for (i = 2; i <= sqrt(n); i++) { if (n % i == 0) { return -1; } } return 1; } int main() { int i = 0; int count = 0; for (i = 100; i < 200; i++) { if (IsPrime(i) == 1) { printf("%d ", i); count++; } } printf("\nThe Number Is %d", count); return 0; }
判断一年是不是闰年。
int is_leap_year(int y)//闰年 { return( (y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)); } int main() { int year = 0; int i = 0; int count = 0; for (i = 1000; i <= 2000; i++) { if (is_leap_year(i) == 1) { printf("%d ", i); count++; } } printf("\n%d\n", count); return 0; }
实现一个整形有序数组的二分查找
int BinarySearch(int* arr, int k, int size) { int left = 0; int right = size - 1; int mid = 0; while (left <= right) { mid = left + (right - left) >> 2;//计算中间元素的下标,防止数据溢出 if (arr[mid] == k) { return mid; } if (arr[mid] > k) { right = mid - 1; } if (arr[mid] < k) { left = mid + 1; } } return -1; } int main()//使用函数封装一个二分查找 { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int size = sizeof(arr) / sizeof(arr[0]); int k = 4;//记录要查找的数 int ret = BinarySearch(arr, k, size); if (ret == -1) { printf("Not Find!\n"); } else { printf("The Number Is Found! The Composition Is %d!\n", ret); } return 0; }
每调用一次这个函数,就会将 num 的值增加1。
void Plus(int* p) { (*p)++;//++的优先级大于* } int main() { int num = 0; int i = 0; for (i = 0; i < 8; i++) { Plus(&num); printf("%d ", num); } return 0; }