unsigned char blind[32] = "and my kingdom too for a blinder";
Это дает ошибку:
a value of type "const char [33]" cannot be used to initialize an entity of type "unsigned char [32]"C/C++(144)
Я не понимаю, почему это дает ошибку.
Я пытаюсь использовать библиотеку C в проекте C++ и хотел отправить тип, который запрашивала библиотека C.
Я думаю, что было бы проще начать с более коротких строк: sizeof("") == 1
(единственный символ — это скрытый '\0'
, sizeof("a") == 2
(это 'a'
, за которым следует '\0'
).
Почему был удален тег C++? Сообщение об ошибке является ошибкой C++, а не ошибкой C
Строки C не сохраняют свою длину, поэтому для обозначения конца строки используется «нулевой терминатор» (символ \0
). Это добавляет один дополнительный байт к строке. Поскольку вы инициализируете строковый литерал, он игнорирует [32]
и использует длину вашей фактической строки, которая включает скрытый терминатор.
Спасибо, когда я изменился на: ``` {'a','n','d',' ','m','y',' ','k','i','n',' g','d','o','m',' ','t','o','o',' ','f','o','r',' ','a ',' ','b','l','i','n','d','e','r'}, ``` это сработало.
@lukas важен нулевой терминатор. Вы должны сохранить это
@lukas обратите внимание, что с вашим решением у вас больше нет действительной строки
@lukas Будьте осторожны с решением, которое вы разместили в комментарии. Если функция C ожидает строку в стиле C, вы делаете это неправильно. Но мы не можем сказать наверняка, так как вы никогда не говорили, для чего будут использоваться данные....
[32] не игнорируется.
О да, нулевой терминатор очень важен. Спасибо!
@Raildex Массив символов C не содержит \0?
@lukas "and my kingdom too for a blinder"
— строковый литерал. Он содержит 32 «видимых» символа и невидимый нулевой терминатор — следовательно, это массив из 33 символов. Что вам нужно сделать, это изменить количество символов вашей переменной: unsigned char blind[33] = "and my kingdom too for a blinder";
@Raildex Да, теперь я понимаю свою проблему, спасибо. Но строка с ошибкой в C++ успешно скомпилирована в C. Я полагаю, что C автоматически не добавляет терминатор NULL? C и C++ по-разному обрабатывают строку, что является основной причиной?
Нет необходимости использовать unsigned char [], если вы будете работать только с символами, символами и числами, поскольку все эти данные находятся в диапазоне простого char (который в основном представляет собой 8-битный тип данных в дополнении 2).
Во-вторых, если вы хотите быстро инициализировать char [], вы можете использовать библиотеку string.h, которая является стандартной и действительно полезной библиотекой, просто включите ее. Затем просто скопируйте свою строку в переменную, учитывая, что вы должны оставить место для конечного символа '\0', который неявно помещается в строки (char []), чтобы библиотека string.h могла определить конец строки (char[ ]).
char blind[33];
strcpy(blind,"and my kingdom too for a blinder");
printf("%s", blind);
вывод: и мое королевство тоже для шоры
char blind[33] = "and my kingdom too for a blinder";
достаточно
Использование strcpy
таким образом означает, что если вы ошибетесь с длиной, вместо ошибки компилятора вы получите переполнение буфера. Плохая идея.
@ user2357112, затем проверьте длину перед ее использованием, но назначение строки в объявлении не является универсальным. Если вы хотите объявить постоянную строку, например, сообщение об ошибке, то следует использовать макрос #define, а не char [], это пустая трата памяти.
Кроме того, использование strcpy
— это назначение во время выполнения, а не инициализация. Это всегда медленнее, чем инициализация, поэтому все, что вы получили, это код помедленнее.
И если вы беспокоитесь о пустой трате памяти, объявите массив как const char[]
на случай, если его не следует изменять.
const char[] продолжает использовать ту же память, что и char[], просто не изменяемая
@LexFerrinson Это зависит от системы. Во встроенных системах вы обычно заметите значительную разницу, поскольку переменная только для чтения перемещается из ОЗУ во флэш-память.
проблема состоит в том, что "and my kingdom too for a blinder"
является строковый литерал типа const char[33]
, а не const char[32]
. Последний символ — нулевой символ '\0'
. Это означает, что строковый литерал "and my kingdom too for a blinder"
эквивалентен:
{'a', 'n', 'd', ' ', 'm', 'y', ' ', 'k','i','n','g','d','o','m',' ','t','o','o',' ','f','o', 'r', ' ', 'a', ' ', 'b', 'l', 'i', 'n', 'd', 'e', 'r', '\0'}
Обратите внимание, что в приведенном выше const char
эквивалентном массиве есть 33
символы, включая нулевой символ '\0'
.
Для решить просто измените размер целевого массива, как показано ниже:
//---------vv------------------------------------------->changed to 33
char blind[33] = "and my kingdom too for a blinder";
"and my kingdom too for a blinder"
— это сокращение от{'a', 'n', 'd', '...', 'd', 'e', 'r', '\0'}
.