Каждый раз в CI приходится передавать ссылку на структуру при каждом вызове функции структуры данных, например, так:
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
as:
(Предположим, что внутри 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;
}