Я не получил никакого предупреждения компилятора при объявлении строки следующими способами
Вы не должны этого делать, поскольку весьма вероятно, что uint8_t
соответствует unsigned char
.
(Вымышленные, теоретические компиляторы, которые поддерживают uint8_t
, но не разрешают его как символьный тип, будут сломаны, бесполезные реализации.)
В чем разница между (2) и (3)
Возможно, продолжительность соединения и хранения. Зависит от того, где переменные объявлены. Это не имеет ничего общего с uint8_t
или строками как таковыми.
Это нормально или плохая практика программирования?
Можно использовать uint8_t
для строк, но немного странно в случае программирования generi c C.
Существуют особые случаи, такие как определенные виды встроенных систем, которые хотят гарантировать, что символы всегда имеют тип без знака, потому что они генерируют таблицы отображаемых символов или строковые протоколы и т. Д. c. В таких системах всегда следует использовать uint8_t
или unsigned char
и никогда char
.
Кроме того, как строка хранится в памяти?
Как 3 байты, инициализированные нулевым значением (0x00). Не путать с символом ноль '0'
(0x30).
Где сохраняется снова, зависит от области, в которой он объявлен. Обратите внимание, что хранится сам строковый литерал в другой памяти, чем массив чтения / записи. Промышленный стандарт де-факто - это что-то вроде этого примера .
Есть ли вероятность, что мы напишем за пределами размера 3?
Да, если вы делаете глупости вроде test[3] = '\0';
. Массив, объявленный с размером 3, может обращаться только к элементам 0, 1 и 2, поскольку индексирование массива индексируется нулями в C.
test [3] = '\ 0' ... Где хранится ли нулевой терминатор?
Никто не знает, это неопределенное поведение. Это не гарантированно хранится где-либо, и ваша программа может взломать sh. Или вам не повезло, и ваша система позволяет вам писать в эту область памяти.
В чем разница между test[3] = ""
и test[3] = '\0'
Первый является синтаксической ошибкой, последняя записывает за пределы массива. Ни один из них не является правильным.
, поэтому я запутался
Вы не понимаете, как декларировать массив по сравнению с доступом к массиву. Они выглядят одинаково, но делают разные вещи. uint8_t test[3] = "";
может использоваться только во время объявления / инициализации. [3]
во время объявления означает массив размера 3. Но [3]
во время доступа к массиву означает доступ к элементу 3 в массиве с нулевым индексом, который имеет только элементы [0]
, [1]
и [2]
.
Инициализатор ""
эквивалентен {'\0'}
, нулевое завершение. Кроме того, в C есть правило, гласящее, что если массив частично инициализирован, все элементы, которые не были явно инициализированы, будут неявно инициализированы равными нулю. В случае ""
первый элемент явно инициализируется нулем, потому что это нулевой терминатор, а остальные неявно равны нулю, потому что так работают массивы.