C预处理器魔术,可删除对数据结构的冗余引用

时间:2018-10-08 04:51:12

标签: c data-structures macros c-preprocessor

每次在C语言中,每次调用这样的数据结构函数时,我都必须传递对结构的引用:

struct Array array; // array struct with int *buffer and size_t size
int size = 100;

array_init(&array, size);
array_add(array, 0, 20); // reference to array, position, value

但是,执行此操作的一种非常简单的方法是将array_add调用为:

(假设struct Array中有一个指向add的指针array_add

array->add(array, 0, 20);

这使代码非常像对象。但是,数组引用仍然作为参数存在。

因此,我认为是否有可能使用某种预处理器魔术而不必每次都传递数组引用(如果出现任何想法,也有一个this引用将非常有帮助)。

到目前为止,我已经明白了:

#define N->display() N->_display(N) // this doesn't work :(
// would eventually do this macro for every function

typedef struct Array_s
{
    size_t size;
    int *buffer;

    int (*_insert)(struct Array_s*, size_t, int);
    int (*_display)(struct Array_s*);

} Array_t, *Array;


int _arr_init(Array *arr, size_t size);

int _arr_insert(Array arr, size_t index, int value);

int _arr_display(Array arr);


int _arr_init(Array *arr, size_t size)
{
    if (size == 0)
        return 10;

    (*arr) = malloc(sizeof(Array_t));

    if (!(*arr))
        return 5;

    (*arr)->buffer = calloc(size, sizeof(int));

    if (!(*arr)->buffer)
        return 5;

    (*arr)->size = size;

    (*arr)->_insert = _arr_insert;
    (*arr)->_display = _arr_display_raw;

    return 0;
}

int _arr_insert(Array arr, size_t index, int value)
{
    if (arr == NULL)
        return 8;

    if (index >= arr->size)
        return 1;

    if (arr->buffer[index] == 0)
    {
        arr->buffer[index] = value;

        return 0;
    }

    return 1;
}

int _arr_display(Array arr)
{
    if (arr == NULL)
        return 8;

    printf("\n[ ");

    size_t i;
    for (i = 0; i < arr->size - 1; i++)
        printf("%d, ", arr->buffer[i]);

    printf("%d ]\n", arr->buffer[arr->size - 1]);

    return 0;
}

// Delete functions and others are omitted

主要可以做到这一点:

int main(int argc, char const *argv[])
{
    Array arr;

    if (_arr_init(&arr, 100) == 0)
    {
        arr->display(); // doesn't work :(
    }

    return 0;
}

0 个答案:

没有答案