第 11 章 函数
11.7 递归函数
——相当于俄罗斯套娃;一个程序未执行结束会挂起,相当于堆栈
一个函数在函数体内又调用了本身,我们称为递归调用,这样的函数就是递归函数。
递归函数成功执行需满足以下两个条件:
(1)必须有一个明显的结束条件。
(2)必须有一个趋近于结束条件的趋势。
注: 用于循环不好实现的,条件比较分散的情况
【条件】:循环过程中有个需要求的数据结果是已知的,找到 声明变量 与 求解变量的关系
eg:分析阶乘的过程
#include <stdio.h>
/**********************************************************************
* 递归案例
* 1. 计算某个数字阶乘
**********************************************************************/
// 定义函数 计算某个数字的阶乘
int factorial(int n)
{
if (n <= 1)
{
return 1;
}
return n * factorial(n-1);
}
int main()
{
printf("10的阶乘:%d \n", factorial(10));
printf("5的阶乘:%d \n", factorial(5));
printf("3的阶乘:%d \n", factorial(3));
/*
factorial(3) 开始调用 条件不成立 return 3 * factorial(2)
factorial(2) 开始调用 条件不成立 return 2 * factorial(1)
factorial(1) 开始调用 条件成立
factorial(1) 结束调用 return 1
factorial(2) 结束调用 return 2 * 1
factorial(3) 结束调用 return 3 * 2
*/
return 0;
}
11.8 常用系统函数
① 字符串函数
标准库头文件 <string.h>
strlen(str) 返回str的长度,类型是 size_t
strcpy(str1,str2) 将 str2 中的字符串复制到str1中 ——(给字符数组重新赋值,得用strcpy(给字符一个一个替换))
strcat(str1,str2) 将 str2 中的字符串追加到 str1 后面
注:相比于 sizeof,strlen() 不会把字符串结束标记计算在内,也就是说strlen() 只计算结束标识符之前的内容
标准库头文件 <stdio.h>
sprintf(),用于将格式化数据写入字符串。 ——这个比较常用
相比于 printf(),多了一个参数,第一个参数是要【写入的字符串】,后面参数与 printf() 一致。
简单地讲,sprintf() 是【将内容写入字符串】而不是输出。
sscanf(),用于从一个字符串中按照指定的格式提取数据。
相比于 scanf(),多了一个参数,第一个参数是要【提取数据的字符串】,后面参数与 scanf() 一致。
简单地讲,sscanf() 是【从字符串中提取数据】而不是从用户输入提取数据。
② 日期时间函数
标准库头文件 <time.h>
time(&变量) 【获取当前日期】赋值到变量中,该变量需是 time_t 类型
ctime(&时间值) 【将时间戳转为字符串】并返回,时间值需是 time_t 类型
difftime(时间值1,时间值2) 【返回两个时间值的差】,返回值是 double 类型,时间值需是 time_t 类型
注:time() 函数获取的是当前日期时间的时间戳(unix时间戳)(从1970年1月1日0时0分0秒[UNIX纪年]到指定日期时间的秒数)
③ 数学计算函数
标准库头文件 <stdio.h>
sqrt(x) 计算平方根
cbrt(x) 计算立方根
pow(x,y) 计算x的y次方
fabs(x) 计算x的绝对值
ceil(x) 向上取整 ——让数字变大
floor(x) 向下取整
round(x) 四舍五入取整 ——不区分正负,只看四五数字
trunc(c) 截断小数部分 ——(正数变小,负数变大)
注:以上函数返回的都是 double 类型
第 12 章 指针 pointer
12.1 指针基础
1. 如果一个变量专门用来【存放内存地址】,则它称为指针变量,通常简称为指针。
指针变量的数据类型为:数据类型 *
声明:数据类型 *指针变量名
2. 内存地址
在32位系统中,内存地址通常是32位二进制数字,即4个字节
在64位系统中,内存地址通常是64位二进制数字,即8个字节
3. 取地址运算符 &
通过 & 可以将某个变量的地址获取
如果需要使用 printf 输出一个内存地址,可以使用占位符 %p
4. 取值运算符(解引用运算符) *
可以【获取指针所指向的数据】
12.2 指针运算
① 指针加减整数
指针+n: 地址向后移动n个数据类型大小 ——(增加)
给指针加1,相当于加一个数据类型的字节(一个数组类型的字节,俗称一个元素)
指针-n: 地址向前移动n个数据类型大小
② 指针自增自减
—— 可以遍历数组,不过循环结束后,指针越界
自增:指针向后移动1个数据类型大小
自减:指针先前移动1个数据类型大小
③ 同类型指针相减
得:相差的元素个数(相差的字节数/数据类型大小)【单位都是字节】
后面地址减前面地址得到正数,前面地址减后面地址得到负数
④ 指针比较大小
后面的地址比前面的地址大(地址编号从前向后的)
不同类型的指针,也可以比大小
12.3 指针和数组
① 数组名
可以把数组名当做是【存储了首元素地址的常量】。
指向首元素指针 和 数组名 的相同点 :
-
都是存储着首元素地址的常量
-
都可以解引用
-
都可以加减整数
-
指向首元素指针可以像数组名一样使用
指向首元素指针 和 数组名 的不同点 :
- 数组名不能自增自减
- 数组名不能重新赋值
- sizeof 数组名获取的是整个数组的存储大小
总结:
数据类型 | sizeof 计算结果 | +1 的值 | * 取值(解引用) | 能否重新赋值(可变性) | |
---|---|---|---|---|---|
数组名 | 元素类型[] | 整个数组的存储长度 | 下一个元素地址 | 首元素的值 | 否 |
指向首元素指针 | 元素类型* | 地址的存储长度 | 下一个元素地址 | 首元素的值 | 是 |
数组指针 |
总结
1. 指针的概念
指针是个变量,存储的是地址
2. 取址运算符和取值运算符(解引用)
取地址运算符: &
取值运算符: *
3. 指针运算
3.1 指针加减整数
3.2 指针自增自减
3.3 同类型指针相减
3.4 指针比较大小、判等
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步