C语言核心特性:递归机制与指针操作详解
递归函数的实现原理
递归的本质是函数在执行过程中对自身发起调用,形成层层嵌套的调用链。这与堆栈结构天然契合——每次调用都会将当前状态压入栈中,待深层调用返回后再逐层恢复。
递归可靠运行的两个必要条件:
- 存在明确的终止条件,防止无限循环
- 每次递归调用都向终止条件靠近
以下通过斐波那契数列展示递归的经典应用:
#include <stdio.h>
// 计算斐波那契数列第 n 项
int fib(int idx)
{
if (idx <= 2) {
return 1; // 终止条件
}
return fib(idx - 1) + fib(idx - 2); // 递归向终止条件收敛
}
int main()
{
for (int i = 1; i <= 8; i++) {
printf("fib(%d) = %d\n", i, fib(i));
}
return 0;
}
标准库函数精选
字符串处理
引入 <string.h> 头文件,常用操作如下:
| 函数原型 | 功能说明 |
|---|---|
size_t strnlen(const char *s, size_t maxlen) | 获取字符串有效长度(安全版本) |
char *strncpy(char *dest, const char *src, size_t n) | 带长度限制的字符串复制 |
char *strncat(char *dest, const char *src, size_t n) | 带长度限制的字符串拼接 |
格式化字符串操作(<stdio.h>):
char buf[128];
int val = 42;
snprintf(buf, sizeof(buf), "数值为: %d", val); // 安全写入字符串
int parsed;
const char *src = "数值为: 42";
sscanf(src, "数值为: %d", &parsed); // 从字符串解析数据
时间日期操作
<time.h> 提供的时间工具:
#include <time.h>
#include <stdio.h>
int main()
{
time_t now, past;
now = time(NULL); // 获取当前时间戳
past = now - 86400; // 一天前的秒数
printf("当前: %s", ctime(&now));
printf("间隔: %.f 秒\n", difftime(now, past));
return 0;
}
数学运算函数
<math.h> 中的数值计算工具:
#include <math.h>
double x = 2.5, y = 3.0;
double result;
result = sqrt(x); // 算术平方根
result = cbrt(x); // 立方根
result = pow(x, y); // x 的 y 次幂
result = fabs(-x); // 绝对值
result = ceil(x); // 向正无穷取整 → 3.0
result = floor(x); // 向负无穷取整 → 2.0
result = round(x); // 四舍五入 → 3.0
result = trunc(x); // 截断小数 → 2.0
指针深度解析
指针的本质与声明
指针变量存储的是内存单元的编号,其类型决定了对地址的解释方式:
int *ip; // 指向整型的指针
double *dp; // 指向双精度浮点的指针
void *vp; // 泛型指针,需强制转换后使用
关键运算符:
&:取址运算符,获取变量的内存地址*:间接访问运算符,通过地址读取或修改目标数据
指针的算术运算
指针运算以数据类型宽度为基本单位:
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // 指向首元素
ptr += 2; // 偏移至第3个元素(地址增加 2*sizeof(int))
printf("%d\n", *ptr); // 输出 30
int *qtr = &arr[4];
ptrdiff_t dist = qtr - ptr; // 同类型指针相减,得元素间隔数
指针与数组的关系
数组标识符在表达式中通常退化为指向首元素的指针,但二者存在关键差异:
| 特性 | 数组名 | 指针变量 |
|---|---|---|
| 可修改性 | 不可赋值,地址固定 | 可重新指向其他地址 |
| 自增/自减 | 不支持 | 支持 |
sizeof 结果 | 整个数组的字节数 | 指针本身的字节数(4/8) |
| 访问元素 | arr[i] 或 *(arr+i) | ptr[i] 或 *(ptr+i) |
遍历数组的指针写法:
int nums[] = {5, 9, 13, 17, 21};
int *end = nums + 5; // 末尾元素的下一个位置
for (int *cursor = nums; cursor < end; cursor++) {
printf("%d ", *cursor); // 通过解引用访问当前元素
}
多级指针与常量指针
int value = 100;
int *p1 = &value; // 一级指针
int **p2 = &p1; // 二级指针,指向指针的指针
const int *pc = &value; // 指向常量的指针:不可通过 pc 修改 value
int *const cp = &value; // 常量指针:cp 不可指向其他地址
const int *const cpc = &value; // 双重限制