C 语言进阶:函数指针、typedef、二级指针、const 指针
1. 函数指针
什么是函数指针?
本质:指向函数入口地址的指针。
函数名本质就是一个指针,例如:
c
int add(int a, int b);
add == 函数入口地址 == int (*)(int,int)
因此:
c
int (*op)(int,int) = NULL;
表示:
op 是一个指针,指向"返回 int、接收两个 int 参数"的函数。
1.1 示例:用函数指针实现加法 / 减法的动态选择
代码:
c
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int main()
{
int (*op)(int ,int)=NULL;
int a=10, b=20, num=0;
printf("1:+, 2:-\ninput num:");
scanf("%d",&num);
switch(num)
{
case 1: op = add; break;
case 2: op = sub; break;
default: op = add;
}
int ret = op(a,b);
printf("op result = %d\n", ret);
return 0;
}
1.2 回调函数
在程序运行时才决定具体调用哪个函数,降低耦合、提高灵活性。
如排序函数需要比较方式,可以传入:
lessthen→ 升序greathen→ 降序
这就是典型的回调函数应用。
2. typedef ------ 自定义类型别名
基本用法:
c
typedef unsigned int u32;
typedef int s32;
指针别名:
c
typedef int (*PFUN)(int,int);
PFUN op1 = NULL; // 等价 int (*op1)(int,int)
这样可以让复杂函数指针写法更易读。
3. 二级指针
什么是二级指针?
二级指针 char** 指向一级指针 char*。
使用场景:函数中修改指针的指向
只有"传指针的地址"才能改变外部的指针变量。
示例:使用二级指针在函数中修改主函数的指针
c
#include <stdio.h>
void fun(char** arg_p)
{
*arg_p = "ok";
}
int main()
{
char *p = "hello";
fun(&p);
printf("p is %s\n", p);
}
fun(&p) → 将 p 修改为新的字符串 "ok"。
4. const 与指针的四种组合(重点)
| 写法 | 说明 |
|---|---|
const char *p |
指针指向的内容不能修改(常量指针) |
char const *p |
同上 |
char * const p |
指针本身不能变(指针常量) |
const char * const p |
内容不能改,指针也不能改 |
错误示例(试图修改字符串常量)
c
char *p = "hello";
p[0] = 'a'; // ❌ 运行错误,修改字符串常量
正确方式(使用可写内存):
c
static char a[50] = "hello";
a[0]='a'; // ✔ 可以修改
5. 字符串指针常见错误示例
错误示例 1:返回栈内变量地址(危险)
c
char *fun2()
{
char *p = "hello"; // 指向字符串常量
p[0]='a'; // ❌ 修改常量,错误
return p;
}
正确版本(使用 static)
c
char *fun()
{
static char a[50]="hello";
a[0]='a';
return a;
}
6. 自己实现 strcpy(使用指针)
c
char *mystrcpy(char *dst,char *src)
{
char *tmp = dst;
while (*src)
{
*dst = *src;
dst++;
src++;
}
*dst = '\0';
return tmp;
}
7. 排序函数中使用函数指针(回调函数)
目标:将比较方式封装为回调
c
int lessthen(int a,int b) { return a < b; }
int greathen(int a,int b) { return a > b; }
排序框架:
c
void sort_array(int *a, int len, PFUN fun)
{
for(int j = len - 1; j > 0; j--)
{
if(fun(a[0], a[1])) // 关键点!
{
int t = a[0];
a[0] = a[1];
a[1] = t;
}
}
}
完整示例:
c
PFUN op1 = lessthen;
sort_array(a, 10, op1);
通过修改回调函数,就能改变排序方式。
8. 示例:fill_array / show_array
用于生成随机数组 + 输出数组:
c
void fill_array(s32 *a,u32 len)
{
srand(time(NULL));
for(int i=0;i<len;i++)
a[i] = rand() % 50;
}
void show_array(int *a,int len)
{
for(int i=0;i<len;i++)
printf("%d ", a[i]);
printf("\n");
}