Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Какой тип данных используется для хранения строки?

#cpp #строки #cpp11 #объявление #строковый_литерал


Вот пример кода:

auto size = "Hello, world";
std::cout << sizeof(size);


В консоль выводится 4. Не могу понять, какой тип данных использует компилятор для
хранения этой строки?
    


Ответы

Ответ 1



Строковые литералы в C++ имеют типы константных символьных массивов. Данный литерал "Hello, world" имеет тип const char[13] Используемый в качестве выражения инициализации он неявно преобразуется к указателю на свой первый элемент, который имеет тип const char * Соответственно переменная size имеет тип const char *. Вы можете убедиться в этом, запустив на выполнение следующий фрагмент кода auto size = "Hello, world"; std::cout << typeid(size).name() << std::endl; Если бы вы написали так decltype(auto) size = "Hello, world"; std::cout << sizeof(size) << std::endl; то переменная size была бы ссылкой на строковый литерал и имела тип const char ( & )[13], а оператор sizeof вернул бы значение 13.

Ответ 2



С абстрактно-наивной точки зрения в данном случае приемлемыми типами для левой части инициализации являются const char (&)[13], [const] char[13] и const char *. Поведение, соответственно, будет зависеть о того, как правила языка описывают дедукцию типа для спецификатора auto в такой декларации. Эти правила совпадают со старыми-добрыми классическими правилами дедукции типов шаблонных аргументов для шаблонных функций, которые говорят, что в данном случае должен дедуцироваться тип "указатель" (а не тип "массив" или тип "ссылка"). Т.е. произойти в данном случае должно то же самое, что и примере template void foo(T) { std::cout << sizeof(T) << std::endl; } int main() { foo("Hello, world"); // специализируется как `foo` } При желании, как в вашем случае, так и в примере с функцией выше, вы можете направить дедукцию в другом направлении auto &size = "Hello, world"; и получить size типа const char (&)[13] и sizeof, возвращающий 13. Заметьте, что ни в первом, ни во втором случае не происходит создания копии исходного строкового литерала, т.е. никакого дополнительного "хранения строки" при этом не возникает. "Хранящаяся строка" в этих случаях - это лишь исходный строковый литерал и хранится он так, как он хранился с начала времен: как статический неизменяемый объект.

Ответ 3



Указатель на char sizeof(char *)

Комментариев нет:

Отправить комментарий