Разница в инициализации массива символов
Я делаю следующее для инициализации массива символов:
char a[] = "teststring";
char b[]={'a','a','b','b','a'};
Хотя для первого, если мне нужно получить длину строки, я должен сделать strlen(a)
.... для другой строки я должен сделать sizeof(b)/sizeof(b[0])
,
почему эта разница?
РЕДАКТИРОВАТЬ: (я получил это)
char name[10]="StudyTonight"; //valid character array initialization
char name[10]={'L','e','s','s','o','n','s','\0'}; //valid initialization
Помните, что когда вы инициализируете массив символов, перечисляя все его символы отдельно, вы должны явно указать символ '\0'.
Я получаю это с char b, мы должны добавить '\0' для правильной инициализации.
ДРУГОЙ: Следовательно, массив символов char, называемый myword, может быть инициализирован с помощью последовательности символов с нулевым символом в конце одним из следующих двух операторов:
char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char myword[] = "Hello";
4 ответа
Строковый литерал, как "teststring"
содержит символы между двойными кавычками плюс завершающий char
со значением ноль. Так
char a[] = "ab";
имеет тот же эффект, что и;
char a[] = {'a', 'b', '\0'};
strlen()
ищет этот символ со значением '\0'
, Так strlen(a)
в этом случае вернется 2.
Наоборот, sizeof()
получает фактический размер используемой памяти. поскольку sizeof(char)
1, по определению в стандарте, это означает sizeof(a)
дать значение 3
- это считает 'a'
, 'b'
и '\0'
,
a
является строкой в стиле C, т. е. символьным массивом с нулевым символом в конце Инициализация эквивалентна:
char a[] = {'t','e','s','t','s','t','r','i','n','g','\0'};
b
однако, он не заканчивается нулем, поэтому это не строка в стиле C, вы не можете использовать такие функции, как std::strlen()
потому что они действительны только для строк в стиле C.
Вы всегда можете написать
char b[]={'a','a','b','b','a','\0'};
преодолеть "разницу".
Также обратите внимание
sizeof(b)/sizeof(b[0])
по существу сводится к
sizeof(b)
поскольку sizeof(char)
всегда 1. Ваша формула используется для любых других типов элементов массива.
Строковые литералы расширяются до массивов символов, но также включают завершающий нулевой символ. Так что думаю
char a[] = "teststring";
как будто у вас есть типы этого
char a[] = {'t','e','s','t','s','t','r','i','n','g','\0'};
Правило большого пальца
Всякий раз, когда вы будете использовать strlen()
в массиве char используйте строковые литералы для инициализации. strlen
функцию можно представить как простое сканирование завершающего нулевого символа (\0
) подсчет необходимых итераций.
Слово о размерах
Даже если иногда используется с круглыми скобками, sizeof
является оператором, неотъемлемой частью языка C++ (унаследовано от C раз). В таких случаях, как char c[] = "hello";
, sizeof(c)
вернет 6, что ровно на 1 больше, чем strlen(c)
и вы можете подумать: "давайте пропустим это неэффективное сканирование для терминатора", но sizeof
перестает быть таким "эффективным", как только он работает с указателями, и массивы могут (и будут) использоваться в качестве указателей при необходимости. Посмотрите на следующий пример:
#include <iostream>
// naive approach, don't do that
int myarraysize(char s[])
{
return sizeof(s);
}
int main ()
{
char c[] = "hello";
std::cout << sizeof(c) << " vs " << myarraysize(c) << std::endl;
return 0;
}