Если у меня есть такая структура:
typedef struct
{
unsigned char c1;
unsigned char c2;
} myStruct;
Какой самый простой способ инициализировать эту структуру в 0? Может быть, будет достаточно следующего?
myStruct _m1 = {0};
или мне нужно явно инициализировать каждый член в 0?
myStruct _m2 = {0,0};
Первый вариант самый простой (включает меньше ввода), и он гарантированно сработает, все члены будут установлены в 0
[Ref 1].
Второй вариант более читабелен.
Выбор зависит от предпочтений пользователя или от того, что предписывает ваш стандарт кодирования.
[Ссылка 1] Ссылка на стандарт C99 6.7.8.21:.
Если в закрытом скобками списке меньше инициализаторов, чем элементов или членов совокупности, или меньше символов в строковом литерале, используемом для инициализации массива известного размера, чем элементов в массиве, остаток совокупности должен быть инициализирован неявно, как и объекты, имеющие статическую длительность хранения.
Хорошее чтение: https://stackoverflow.com/questions/10828294/c-and-c-partial-initialization-of-automatic-structure
Если данные являются статической или глобальной переменной, то по умолчанию они заполнены нулями, поэтому просто объявите их myStruct _m;
.
Если данные являются локальной переменной или зоной, выделенной из кучи, очистите их с помощью memset
, например:
memset(&m, 0, sizeof(myStruct));
Современные компиляторы (например, последние версии gcc
) довольно хорошо оптимизируют это на практике. Это работает только в том случае, если все нулевые значения (включая нулевые указатели и нули с плавающей точкой) представлены в виде всех нулевых битов, что верно на всех известных мне платформах (однако стандарт C допускает реализации, в которых это неверно; я не знаю ни одной такой реализации).
Возможно, вы можете написать код myStruct m = {};
или myStruct m = {0};
(даже если первый член myStruct
не является скаляром).
Мне кажется, что использование memset
для локальных структур лучше всего, и оно лучше передает тот факт, что во время выполнения нужно что-то сделать (в то время как обычно глобальные и статические данные можно понимать как инициализированные во время компиляции, без каких-либо затрат во время выполнения).
См. §6.7.9 Инициализация:
21 Если в списке, заключенном в скобки, меньше инициализаторов, чем элементов или членов совокупности, или меньше символов в строковом литерале, используемом для инициализации массива известного размера, чем элементов в массиве. размера, чем элементов в массиве, оставшаяся часть совокупности должна быть инициализироваться неявно, как и объекты, имеющие статическую длительность хранения.
Так что да, оба варианта работают. Обратите внимание, что в C99 можно использовать и новый способ инициализации, называемый назначенной инициализацией:
myStruct _m1 = {.c2 = 0, .c1 = 1};