Это также полезно для диапазонов разделения; диапазон (a, b)
можно разбить на диапазон (a, x)
и (x, b)
, тогда как с включенным диапазоном вы будет писать либо x-1
, либо x + 1
. Хотя вам редко приходится разделять диапазоны, вы часто часто разбиваете списки, что является одной из причин нарезки списка l [a: b]
включает в себя a-ый элемент, но не b- е. Тогда диапазон
, обладающий тем же свойством, делает его хорошо согласованным.
У меня есть структура, содержащая объявление вроде этого:
blockquote>Нет, вы этого не делаете. Это синтаксическая ошибка. Вы ищете:
void (*functions[256])();
Что такое массив указателей на функции. Обратите внимание, однако, что
void func()
не является «функцией, которая не принимает аргументов и ничего не возвращает». Это функция, которая принимает неопределенные числа или типы аргументов и ничего не возвращает. Если вам нужны «никакие аргументы», вам это нужно:void (*functions[256])(void);
В C ++
void func()
означает, что означает «не принимает аргументов», что вызывает некоторую путаницу (тем более, что функциональность C указывает, что дляvoid func()
имеет сомнительное значение.)В любом случае вы должны
typedef
указатель на функцию. Это сделает код бесконечно легче понять, и у вас будет только один шанс (вtypedef
), чтобы получить синтаксис неправильно:typedef void (*func_type)(void); // ... func_type functions[256];
В любом случае вы не можете назначить массив, но вы можете инициализировать массив и скопировать данные:
static func_type functions[256] = { /* initializer */ }; memcpy(struct.functions, functions, sizeof(functions));
Если вы хотите post -инициализировать массив, используя форму типа {func1, func2, ...}
, это может быть выполнено следующим образом (с использованием GCC):
UPD (благодаря Chris Lutz для замечаний)
Определите макрос следующим образом:
#define FUNCTION_VECTOR_COPY(destVec, sourceVec) memcpy(destVec, sourceVec, sizeof(sourceVec))
И передайте исходный вектор, используя Compound Literals , как следует:
#include <string.h>
...
void (*functions[256])();
...
FUNCTION_VECTOR_COPY (functions, ((void(*[])()) {func1, func2, func3}));
sizeof(funcsFrom)
здесь недействителен. Массивы в параметрах функции распадаются на указатели, поэтому ваша функция действительно void setFuncs(void(**funcsTo)(), void(**funcsFrom)())
без информации о sizeof
. Вы должны a) использовать макрос, который позволит вам это сделать, или b) передать размер массива в качестве третьего параметра. И если вы делаете b, вы можете даже c) написать макрос оболочки, который автоматически подключается к третьему аргументу на основе sizeof
второго. Кроме того, d) используйте sizeof(funcsFrom) / sizeof(funcsFrom[0])
в случае изменения типов, и e) ваша функция в противном случае идентична memcpy
.
– Chris Lutz
16 March 2011 в 01:11
sizeof
. (Великий!; (d) - нормально, но сначала вы должны проверить, имеет ли источник-источник размер больше 0; (e) - yep, но вы не должны забывать включать string.h
. См. Обновленный ответ.
– Martin Babacaev
16 March 2011 в 11:20
С вершины моей головы и непроверенной.
// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };
// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];
EDIT: Исправлена синтаксическая ошибка, как сказал Крис Лутц.
Вы можете это сделать, объявив свой экземпляр структуры:
function_structur fs = { struct_field1,
struct_field2,
{function0, function1, ..., function255},
struct_field3,
... };
Вы не можете использовать этот ярлык для инициализации массивов после объявления массива: если вам нужно это сделать, вам придется делайте это динамически (используя цикл, memcpy
или что-то еще).
У меня была та же проблема, это моя небольшая программа для тестирования решения. Это выглядит довольно просто, поэтому я решил поделиться им с будущими посетителями.
#include <stdio.h>
int add(int a, int b) {
return a+b;
}
int minus(int a, int b) {
return a-b;
}
int multiply(int a, int b) {
return a*b;
}
typedef int (*f)(int, int); //declare typdef
f func[3] = {&add, &minus, &multiply}; //make array func of type f,
//the pointer to a function
int main() {
int i;
for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
return 0;
}
Вы можете сделать это динамически ... Вот небольшой пример массива динамических функций, выделенного с помощью malloc ...
#include <stdio.h>
#include <stdlib.h>
typedef void (*FOO_FUNC)(int x);
void a(int x)
{
printf("Function a: %d\n", x);
}
void b(int x)
{
printf("Function b: %d\n", x);
}
int main(int argc, char **argv)
{
FOO_FUNC *pFoo = (FOO_FUNC *)malloc(sizeof(FOO_FUNC *) * 2);
pFoo[0] = (FOO_FUNC)&a;
pFoo[1] = (FOO_FUNC)&b;
pFoo[0](10);
pFoo[1](20);
return 0;
}
assert(sizeof(the_struct.functions) == sizeof(functions))
или аналогичный. – Lundin 15 March 2011 в 11:33sizeof(some_struct)
возвращает размер структуры + любое необходимое дополнение. См. этот вопрос , например. Использованиеmemcpy
выше верно. – Mat 15 March 2011 в 11:43memcpy()
в любом случае не используется в структурах - он используется для копирования из одного массива в другой с одинаковым размером, что отлично. Тот факт, что целевой массив является элементом структуры, не имеет значения. – caf 15 March 2011 в 13:27struct
является ключевым словом, поэтому использование его как имени переменной неверно даже для кода примера, который никогда не будет близок к компилятору. – Chris Lutz 16 March 2011 в 01:06func()
иfunc(void)
является лишь вопросомC++
, а не C, не так ли? – dhein 21 January 2016 в 08:48