Разница в инициализации массива символов

Я делаю следующее для инициализации массива символов:

  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;
}

онлайн демо

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