[Source/wheels]foreach()函數

我最近喜歡上函數式編程了.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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章