我最近喜欢上函数式编程了.JS里的匿名函数,Python中的列表推导都让我大呼过瘾.
可是C语言却不适合函数式编程,毕竟既没有闭包,也没有匿名函数.
但我还是想写一些C语言的函数式编程工具.
我能不能写得了呢?先写了一个foreach().不过,这个跟函数式编程好像没啥关系…?
一.源代码
源代码: https://github.com/tjytlxwxhyzqfw/hdoj/blob/master/Source/wheels.c
void *foreach(const void *first, const int size, const int elementsize,
void * (*f)(const int, const void *),
void *result[], const int ressize) {
int i = 0;
const void *current = first;
if (result) {
while (i < size && i < ressize) {
result[i] = f(i, current);
current += elementsize;
++i;
}
}
while (i < size) {
f(i, current);
current += elementsize;
++i;
}
return (void *)result;
}
二.说明
-遍历一个数组.将给定的函数应用到数组中的每个元素,并存储返回值.
三.参数
first
指向数组中第一个元素的指针.
size
数组中元素的个数
elementsize
数组中元素的大小
f(const int index, const void *current)
这个函数会被应用到数组中的每个元素上.
index是元素在数组中的下标.
current是指向当前元素的指针.
result, ressize
f的所有返回值都会被存储到result中,最多存储ressize个返回值.
多余的返回值会被丢弃.
四.小笔记
1. void *
void *
这种指针,它在+1的时候和”char *”是一样的,都是一个字节一个字节的移动.
2. const
对于下面这两个形参:
- const void * array[]
- void * const array[]
实参void *array[]可以向第二个形参赋值,却无法向第一个形参赋值.
原因在”C专家编程”上有讲.简单来说就是:
- 不带const的实参可以向带有const的形参赋值.
- 但是,const T和T被认为是两种不同类型
于是第一个形参的数组元素是const void *
而形参的数组元素却是void *
,因此不能赋值.
五.后记
我知道这有些傻.
因为对于:
int array[] = {1, 2, 3};
你明明可以:
int i;
for (i = 0; i < 3; ++i)
print("%d: %d\n", i, array[i]);
而现在却要:
void *printint(const int i, const void *ip)
{
int n = *((int *)ip);
printf("%d: %d\n", i, n);
return NULL;
}
foreach(array, 3, sizeof(int), printint, NULL, 0);
可是我依然觉得第二个用起来舒服.
因为不用重复写无聊的for循环了,而且现在我可以把精力集中在处理数组元素本身,而不是控制数组遍历.
作为一个函数式编程界的菜鸟,我感觉这好像不算是函数式编程,毕竟连个纯函数都不是.
然而,这并不能阻止我成为FP的脑残粉:P