-ciox.jpg)
【C】可变长数组和函数指针
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
可变长数组
1. 数组问题
基本数组常见问题
- 数组容量一旦确定无法修改。
- 数组的存储类型无法修改。
- 数组不得作为返回值类型。
设计结构体类型来描述数组,增强数组的功能
2. 可变长数组结构设计
目标存储类型为 Student *,数组中的每一个元素都是一个学生结构体指针。
typedef struct student_array
{
/*
elements 在这里可以认为是一个指针数组,存储类型为Student * 学生结构体指针,
因为当前存储数据的内存空间在内存的堆区,需要通过指针访问。相当于通过当前
elements 指针访问对应的内存空间,得到的是一个 Student * 指针,所以当前
elements 类型是 Student ** 二级指针
*/
Student ** elements;
/*
当前底层 elements 数组的容量
*/
size_t capacity;
/*
当前底层 elements 有效元素个数
*/
size_t size;
} Student_Array;
函数指针
1. 插件式编程逻辑
函数功能主体不变,同时引入不同的操作规则/函数指针,完成当前函数的功能多样式实现,生活中案例有,红白机/游戏机,擦丝器,可替换刀头螺丝刀
2. 函数指针语法要求
【核心理念】
- 替换
- 删除
int my_add(int n1, int n2);
函数名对于当前函数而言是一个【指针常量】,对应当前函数在内存【代码区】的空间首地址。函数指针的类型是根据当前函数的【返回值类型】和【参数类型】决定
如果需要定义一个函数指针用于存储
my_add
函数在内存中的首地址。格式
// 根据已知函数声明,分析当前的函数数据类型,推演对应函数指针定义形式
// 1. 【替换】将函数名替换为 (*函数指针名)
my_add ==> (*p_fun);
// 2. 【删除】删除函数形式参数列表中的参数变量名称
(int n1, int n2) ==> (int, int);
// 整合之后, 当前函数指针变量为,当前函数指针可以存储的函数地址
// 要求
// 1. 返回值为 int 类型,
// 2. 参数必须是两个 int 类型。
int (*p_fun)(int, int);
3. 函数指针案例
#include <stdio.h>
int my_add(int n1, int n2);
int main(int argc, char const *argv[])
{
/*
根据当前 my_add 函数定义一个函数指针
函数名是当前函数在内存代码区的空间首地址。
*/
int (*p_fun)(int, int) = my_add;//定义函数指针
printf("p_fun : %p\n", p_fun);
printf("my_add : %p\n", my_add);
printf("my_add(10, 20) : %d\n", my_add(10, 20));
printf("p_fun(10, 20) : %d\n", p_fun(10, 20));
return 0;
}
int my_add(int n1, int n2)
{
return n1 + n2;
}
4. 函数指针作为函数的参数【重点】
#include <stdio.h>
int my_add(int n1, int n2);
int my_sub(int n1, int n2);
int my_mul(int n1, int n2);
int my_div(int n1, int n2);
/**
* 当前函数所需参数是两个 int 类型数据,和一个函数指针,函数指针要求
* 提供的函数,必须是返回值为 int 类型,参数有是两个 int 类型函数。
*
* @param n1 用户提供的 int 类型数据
* @param n2 用户提供的 int 类型数据
* @param p_fun 用户指定处理当前两个 int 类型数据的函数。
* @return 返回值是当前函数指针指向函数执行结果。
*/
int operate(int n1, int n2, int (*p_fun)(int, int));
int main(int argc, char const *argv[])
{
/*
函数所需参数是一个函数指针,需要提供给函数的实际参数
是满足函数指针限制的函数名称。
*/
int ret = operate(10, 20, my_add);
printf("ret : %d\n", ret);
ret = operate(100, 20, my_sub);
printf("ret : %d\n", ret);
ret = operate(10, 20, my_mul);
printf("ret : %d\n", ret);
ret = operate(100, 20, my_div);
printf("ret : %d\n", ret);
return 0;
}
int operate(int n1, int n2, int (*p_fun)(int, int))
{
return p_fun(n1, n2);
}
int my_add(int n1, int n2)
{
return n1 + n2;
}
int my_sub(int n1, int n2)
{
return n1 - n2;
}
int my_mul(int n1, int n2)
{
return n1 * n2;
}
int my_div(int n1, int n2)
{
return n1 / n2;
}
5. 函数指针作为过滤函数条件限制实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.h"
void filter_student_data1(Student **stu_array);
void filter_student_data2(Student **stu_array);
/**
* 谓语判断,对提供的 Student * 数据进行判断,返回结果是一个
* int 类型数据,满足条件返回 1,否则返回 0
*
* @param stu Student * 结构体指针
* @return 函数内部进行数据判断,满足返回 1,否则返回 0
*/
int predicate(Student * stu);
/**
* 使用 predicate 谓语函数作为当前过滤展示 Student * 条件内容,要求用户提供的
* 参数为 Student * 指针数组,和 处理过滤当前 Student * 条件的函数指针,要求函数
* 指针返回值类型必须是 int 类型,参数类型必须是 Student * 类型。
*
* @param stu_array Student * 指针数组
* @param predicate 函数指针,要求提供的函数返回值为 int ,参数为 Student *
*/
void filter_student_data_using_predicate(Student **stu_array, int (*predicate)(Student *));
int main(int argc, char const *argv[])
{
Student **stu_array = (Student **)calloc(10, sizeof(Student *));
for (size_t i = 0; i < 10; i++)
{
stu_array[i] = create_new_student(i + 1, "James", i * 5, 'M');
}
#if 0
filter_student_data1(stu_array);
printf("=----------------------------------=\n");
filter_student_data2(stu_array);
#endif
filter_student_data_using_predicate(stu_array, predicate);
for (size_t i = 0; i < 10; i++)
{
release_student(stu_array[i]);
}
return 0;
}
int predicate(Student * stu)
{
return stu->id < 6;
}
void filter_student_data_using_predicate(Student **stu_array, int (*predicate)(Student *))
{
for (size_t i = 0; i < 10; i++)
{
// 直接利用函数指针作为 if 条件判断依据
if (predicate(stu_array[i]))
{
show_student_data(stu_array[i]);
}
}
}
void filter_student_data1(Student **stu_array)
{
for (size_t i = 0; i < 10; i++)
{
if (stu_array[i]->age > 20)
{
show_student_data(stu_array[i]);
}
}
}
void filter_student_data2(Student **stu_array)
{
for (size_t i = 0; i < 10; i++)
{
if (stu_array[i]->id < 3)
{
show_student_data(stu_array[i]);
}
}
}
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载必须注明来自 卡卡罗特
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果