Инициализация структуры в 0

Если у меня есть такая структура:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

Что было бы самым простым способом инициализировать эту структуру в 0? Будет ли достаточно следующего?

myStruct _m1 = {0};

или мне нужно было бы явно инициализировать каждого члена в 0?

myStruct _m2 = {0,0};

3 ответа

Решение

Первый - самый простой (требует меньше ввода), и он гарантированно сработает, все участники будут настроены на 0[Ссылка 1].
Второе более читабельно.

Выбор зависит от предпочтений пользователя или того, который требует ваш стандарт кодирования.

[Ссылка 1] Ссылка C99 Standard 6.7.8.21:

Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или членов агрегата или меньше символов в строковом литерале, используемом для инициализации массива известного размера, чем элементов в массиве, оставшаяся часть агрегата должна инициализироваться неявно так же, как объекты, которые имеют статическую длительность хранения.

Хорошо для чтения:
C и C++: частичная инициализация автоматической структуры

Если данные являются статической или глобальной переменной, они по умолчанию заполнены нулями, поэтому просто объявите их 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};

Я тоже думал, что это сработает, но это вводит в заблуждение: myStruct _m1 = {0};

Когда я попробовал это: myStruct _m1 = {0xff};

Только 1-й байт был установлен в 0xff, остальные были установлены в 0. Так что я бы не привык использовать это.

Другие вопросы по тегам