Что лучший способ состоит в том, чтобы выполнить следующее в C?
#include <stdio.h>
struct A
{
int x;
};
struct A createA(int x)
{
struct A a;
a.x = x;
return a;
}
struct A a = createA(42);
int main(int argc, char** argv)
{
printf("%d\n", a.x);
return 0;
}
Когда я пытаюсь скомпилировать вышеупомянутый код, компилятор сообщает о следующей ошибке:
"элемент инициализатора не является постоянным"
Плохая строка - этот:
struct A a = createA(42);
Кто-то может объяснить что не так? Я не очень опытен в C.Спасибо!
Почему бы не использовать статическую инициализацию?
struct A a = { 42 };
Вы не можете вызывать функции при такой статической инициализации. В вашем примере вы можете просто использовать:
struct A a = {42};
Если у вас более сложная установка, вам нужно будет предоставить функцию создания библиотеки и уничтожения библиотеки, которую вы заставляете вызывать пользователей вашей библиотеки (при условии, что вы хотите быть переносимым), или вам придется использовать C ++ и воспользоваться конструкторами / деструкторами, или вам придется воспользоваться нестандартным и непереносимым __attribute __ ((constructor)), чтобы создать функцию, которая запускается при запуске для ее инициализации.
Если у вас более сложная настройка, я настоятельно рекомендую вам использовать C ++:
class A { A(){ // can do initialization in the constructor } // ... }; A a;
Однако, если вам нужно придерживаться чистого C, переносимая вещь, которую нужно сделать, - это использовать что-то вроде:
typedef void* mylibrary_attr_t; typedef void* mylibrary_t; #ifdef __cplusplus # define EXTERNC extern "C" #else # define EXTERNC #endif EXTERNC int mylibrary_attr_init(mylibrary_attr_t*); EXTERNC int mylibrary_attr_setparam1(mylibrary_attr_t,int); EXTERNC int mylibrary_attr_setparam2(mylibrary_attr_t,double); // .. more functions for various attributes used by library EXTERNC void mylibrary_attr_destroy(mylibrary_attr_t*); EXTERNC int mylibrary_init(mylibrary_t*,mylibrary_attr_t); EXTERNC void mylibrary_destroy(mylibrary_t*); // functions that use mylibrary_t // ...
В основном, в выше, вы должны инициализировать свою библиотеку с помощью mylibrary_init
и удалить свою библиотеку с помощью mylibrary_destroy
. Для функций, использующих вашу библиотеку, потребуется инициализированный экземпляр mylibrary_t
, поэтому человек, создавший основную функцию, будет нести ответственность за вызов mylibrary_init
. Также хорошо сделать функцию инициализации зависимой от параметра «атрибуты», который по умолчанию можно заменить на 0 или NULL. Таким образом, если вы расширяете свою библиотеку и вам нужно принять параметры конфигурации, она будет вам доступна. Однако это больше дизайн, чем технический подход.
Проблема здесь в том, что глобальные / файловые статические переменные в C должны иметь значение, известное во время компиляции. Это означает, что вы не можете использовать пользовательскую функцию для инициализации значения. Это должно быть постоянное выражение
struct A a = { .x = 42 };
Больше участников:
struct Y {
int r;
int s;
int t;
};
struct Y y = { .r = 1, .s = 2, .t = 3 };
Вы также можете сделать
struct Y y = { 1, 2, 3 };
То же самое работает для профсоюзов, и вам не нужно включать всех участников или даже расположите их в правильном порядке.
Вы не можете вызывать функцию как initiliazer. Вы должны вызывать ее внутри main.