Страницы

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

среда, 17 октября 2018 г.

sizeof для символа кириллицы

Я провел несколько экспериментов, но объяснить почему это так работает я не смог
Пример 1:
#include int main() { /// латиница printf("
%d",sizeof('a')); /// 1 /// кириллица printf("
%d",sizeof('ф')); /// 4 return 0; }
Пример 2:
#include int main() { char a = 'a'; /// латиница char b = 'ф'; /// кириллица printf("
%d",sizeof(a)); /// 1 printf("
%d",sizeof(b)); /// 1 return 0; }
Вообще ничего не понимаю объясните! P.S Компилятор g++


Ответ

Символьные (и строковые) литералы в коде программы так или иначе переводятся компилятором в последовательность байт. Правило этого преобразования зависит от кодировки исходника (как уже упоминали другие участники), но может зависеть и ещё от ряда факторов (см. ответ на другой вопрос).
Следует заметить, что оба варианта Вашего кода при попытке компиляции компилятором clang приводят к ошибке
error: character too large for enclosing character literal type char b = 'ф'; /// кириллица
А используемый Вами gcc даёт пару предупреждений для строки с буквой ф
warning: multi-character character constant [-Wmultichar] warning: overflow in implicit constant conversion [-Woverflow]
Первое говорит об использовании мультисимвольного литерала (что поддерживается не всеми компиляторами). Второе - о том, что этот литерал не помещается в char. Т.е. тип 'ф' компилятором был интерпретирован как нечто большее, чем char, и, как уже упоминалось в цитате из ответа @Harry, этот тип есть int:
... has type int, and has an implementation-defined value.
Исходя из вышесказанного, можно сделать вывод:
4 (пример 1) получается, т.к. мультисимвольный литерал не усекается и его размер равен размеру int, т.е. sizeof(int) == 4 1 (пример 2) получается, т.к. мультисимвольный литерал был усечён до типа char при инициализации переменной b, а sizeof(char) == 1 по определению.

Отвечу здесь и на Ваш комментарий к другому сообщению:
я представлял себе многобайтовый литерал как один символ из сложной кодировки допустим 'ф' (UTF-8) а это 2 байта выходит мы можем по вашим словам записать не более 2х 'ф'...несостыковочка с 4мя символами
Записать более 2х 'ф' у Вас действительно не получится
#include int main() { printf("
%d",sizeof('ффф')); }
warning: character constant too long for its type
Т.е. фактически происходит усечение значения до sizeof(int)
Но если будет использован строковый литерал, то для хранения ф вполне может хватить двух байт
#include int main() { const char c[] = "ф"; printf("%ld
", sizeof(c)); }
3
Выводит число 3, т.к. 1 байт отводится под терминирующий ноль.

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

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