Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
1

Символьные литералы

23.12.2018, 15:38. Показов 1443. Ответов 24
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
 
int main()
{
    char ch=36;
    cout << ch;
}
Программа печатает доллар. Тестировал здесь: http://www.cpp.sh/

А почему 36 это доллар? Зависит ли это:
от компилятора?
от системы?
от устройства?
от кодировки, в которой сохранён исходник?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.12.2018, 15:38
Ответы с готовыми решениями:

Символьные литералы, указатели и функция. Не могу понять, почему именно так
Доброго времени суток всем! :) Изучаю С++, всегда стараюсь добить до последнего код, чтобы не...

Литералы
Добрый день! Уже весь инет перерыл в поисках необходимости понятия значения литерал в С++. Будьте...

литералы в С++
Никак не могу разобраться float A = 5.5F зачем это(5.5F) нужно, нет я понимаю что тип с плавающей...

Литералы
Сейчас пытаюсь изучать программирование, в книге рассказывают про литералы и я просто ошалел, что...

24
El. Psy. Congroo.
110 / 92 / 32
Регистрация: 09.01.2018
Сообщений: 344
23.12.2018, 18:39 2
Таблица ASCII.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
24.12.2018, 21:29  [ТС] 3
Хорошо, вот имеется другой код:
C++
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;
 
int main()
{
    char ch='æ';
    cout << 1*ch;
}
Программа печатает -90. Я хочу понять, как получилось число -90, и как вообще в таких случаях устанавливается соответствие между символом в исходнике и числом из диапазона char.

Добавлено через 9 минут
Ой, что-то здесь в кавычках не то пропечаталось. В оригинале я инициализировал переменную ch значением 'æ'.

Добавлено через 3 минуты
Если кого-то интересуют warning-и, которые были получены при компиляции кода, то вот warning-и:

6:13: warning: multi-character character constant [-Wmultichar]
In function 'int main()':
6:13: warning: overflow in implicit constant conversion [-Woverflow]
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
24.12.2018, 21:33 4
Цитата Сообщение от Jzx Посмотреть сообщение
хочу понять, как получилось число -90, и как вообще в таких случаях устанавливается соответствие между символом в исходнике и числом
Вам уже дали подсказку: таблица кодировки. Сейчас в большинстве случаев для кодов [0;127] используется ASCII, для других кодов необходимо смотреть соответствующую таблицу кодировки. Это может быть Windows-1251 (у вас скорее всего она), UTF-8 или другая.

Цитата Сообщение от Jzx Посмотреть сообщение
char ch='Г¦';
Это неправильно. Один символ должен определяться одним символом, а у вас написано два.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
24.12.2018, 21:51  [ТС] 5
Цитата Сообщение от valen10 Посмотреть сообщение
Это неправильно. Один символ должен определяться одним символом, а у вас написано два.
æ — это один символ
Цитата Сообщение от valen10 Посмотреть сообщение
Вам уже дали подсказку: таблица кодировки. Сейчас в большинстве случаев для кодов [0;127] используется ASCII, для других кодов необходимо смотреть соответствующую таблицу кодировки. Это может быть Windows-1251 (у вас скорее всего она), UTF-8 или другая.
Мне не дали подсказки: всевозможных символов сотни тысяч по миру, если не миллионы. При этом стандарт гарантирует лишь 256 кодов, которые можно хранить в char.
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
24.12.2018, 22:01 6
Цитата Сообщение от Jzx Посмотреть сообщение
æ — это один символ
Однако у вас там заглавная Г и изломанная вертикальная черта ¦. Считаете, что нет разницы?

Цитата Сообщение от Jzx Посмотреть сообщение
всевозможных символов сотни тысяч по миру, если не миллионы. При этом стандарт гарантирует лишь 256 кодов, которые можно хранить в char.
Это как-то противоречит одно другому?
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
24.12.2018, 22:18  [ТС] 7
Цитата Сообщение от valen10 Посмотреть сообщение
Однако у вас там заглавная Г и изломанная вертикальная черта ¦.
Это не у меня, это на форуме. Я набрал другой символ в своём сообщении.
Цитата Сообщение от valen10 Посмотреть сообщение
Считаете, что нет разницы?
Задайте этот вопрос через форму обратной связи: https://www.cyberforum.ru/sendmessage.php
Цитата Сообщение от valen10 Посмотреть сообщение
Это как-то противоречит одно другому?
Не противоречит, но есть проблема: в исходниках вы можете набрать одни символы, а после компиляции в консольном выводе получить совершенно другие. Мне хотелось бы понять, как обойти эту проблему и сам механизм её возникновения.
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
24.12.2018, 22:32 8
Вот вам информация для размышления. Есть такая программа:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <cstring>
#ifdef _WIN32
#include <Windows.h>
#endif
using namespace std;
 
int main() {
#ifdef _WIN32
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
#endif
 
    char str[] = "English && Русский";
    cout << str << endl;
    cout << "Length: " << strlen(str) << endl;
 
    for (char c : str) {
        cout << (int)c << " ";
    }
 
    cout << endl;
 
#ifdef _WIN32
    system("pause");
#endif
    return 0;
}
Вопрос: чему равна длина строки и какие коды будут напечатаны? Рекомендую сначала подумать и сделать предположение. Затем скопировать и запустить код, чтобы проверить свое предположение. Правильный ответ под спойлером.

Кликните здесь для просмотра всего текста

Невозможно дать однозначный ответ, т.к. результат зависит от используемой кодировки.

Можно предположить, что длина строки равна 18, т.к. в ней именно столько букв. И при запуске в Windows результат скорее всего совпадет, т.к. там основной кодировкой является однобайтовая Windows-1251 (национальный вариант ASCII), которая позволяет закодировать всего 256 различных символов, включая служебные.

Символьные литералы


Результат в Linux окажется иным, поскольку основной кодировкой там является многобайтовая UTF-8. Функция strlen() на деле считает не количество букв, а количество ненулевых кодов.

Символьные литералы


Можно также заметить, что первые 11 кодов в обоих случаях одинаковые, т.к. английские буквы и некоторые символы и там, и там кодируются младшей половиной таблицы ASCII.

На Википедии есть такая таблица.
Символьные литералы


Находим в ней заглавную английскую E, ей соответствует код 0x45 (69 в десятичной системе). Смотрим на вывод программы: первый код 69. И так далее для остальных букв. Надеюсь, понятно объяснил.

1
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
24.12.2018, 22:49  [ТС] 9
valen10, вы предполагаете, что мне известно, как работают функции SetConsoleCP, SetConsoleOutputCP и директивы #ifdef и #endif. Увы, это не так: я начал изучать язык относительно недавно.

Я думаю (в попытках самостоятельно ответить на свой вопрос), что для достижения правильного результата необходимо, чтобы кодировка командной строки совпадала с кодировкой исходника.

valen10, насчёт вашего вопроса: увы, не могу ответить ничего вразумительного. Для ответа мне требуется знать те возможности языка, которые вы используете в своём коде.
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
24.12.2018, 22:55 10
Jzx, вы смотрите не на ту часть программы. SetConsoleCP и SetConsoleOutputCP меняют кодировку в консоли, это можно было поискать в интернете.

Цитата Сообщение от Jzx Посмотреть сообщение
Для ответа мне требуется знать те возможности языка, которые вы используете в своём коде.
Сделать предположение о длине строки можно было просто посчитав количество букв. Если ничего не делать, то останется только топтаться на месте.
0
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
24.12.2018, 23:16 11
Jzx, для начала вдумчиво прочитать это.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
25.12.2018, 12:15  [ТС] 12
Цитата Сообщение от valen10 Посмотреть сообщение
Результат в Linux окажется иным, поскольку основной кодировкой там является многобайтовая UTF-8. Функция strlen() на деле считает не количество букв, а количество ненулевых кодов.
Я, кажется, понял в чем дело: 25-18=7. Эти 7 байт есть дополнительные байты, необходимые для хранения 7 русских букв. strlen подсчитывает число байт, необходимых для хранения всех символов, кроме завершающего.
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.12.2018, 12:37 13
Jzx, верно, хороший вывод. Почитайте еще про Unicode (Юникод: необходимый практический минимум для каждого разработчика), чтобы до конца разобраться. Это довольно хорошая штука, если вы хотите использовать любые символы без риска получить кашу из кракозябр. Правда консоль Windows его не переваривает, в ней можно использовать только 256 символов текущей кодовой таблицы.

Связана ли кодировка вывода программы с кодировкой исходника? Похоже, что нет. Последние версии Visual Studio позволяют хранить (и по умолчанию так и делают) исходник в UTF-8, однако после компмляции вывод текста происходит в кодировке Windows-1251 (для русской версии системы). При этом символы конвертируются, если для них есть соответствующие символы в текущей таблице. Если же какого-то символа там нет, вместо него ставится знак ?.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
25.12.2018, 12:48  [ТС] 14
Цитата Сообщение от valen10 Посмотреть сообщение
Связана ли кодировка вывода программы с кодировкой исходника? Похоже, что нет.
В смысле? Ведь char — это ведь целочисленный формат. Компилятор должен преобразовывать символы исходника в байты памяти в зависимости от кодировки исходника. Дальше эти байты на этапе исполнения программы считываются и выводятся в консоль в соответствии с той кодировкой, которая используется в консоли.

Что не так?
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.12.2018, 12:50 15
К строковым литералам кстати можно добавить префикс u8, чтобы явно сообщить о своем намерении использовать кодировку UTF-8, но консоли Windows это тоже не понравится. Тут обсуждали значения префиксов и возможности C++ по работе с разными кодировками. Посмотрите, если интересно.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
25.12.2018, 12:51  [ТС] 16
valen10, вы имели в виду, что информация о том, как был закодирован исходник, теряется на этапе компиляции?
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
25.12.2018, 13:07 17
Цитата Сообщение от Jzx Посмотреть сообщение
Что не так?
Где сказано, что компилятор должен делать именно так? Кодировка исходника может быть и другой, но это не должно влиять на результат компиляции. Файлы исходника анализируются по содержимому, формат их хранения не важен. Строки и переводятся в байты. Только вот не верно, что они потом выводятся в соответствии с кодировкой консоли. Они выводятся точно те же, что и были записаны на этапе компиляции, а уже консоль рисует графическое представление символов в соответствии со своей таблицей кодировки. А в разных таблицах одним и тем же кодам могут соответствовать разные символы. Если эти таблицы не совпадут, вы увидите совсем не то, что ожидали.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
25.12.2018, 16:56  [ТС] 18
Цитата Сообщение от valen10 Посмотреть сообщение
Строки и переводятся в байты.
По каким правилам? Каким способом?
Цитата Сообщение от valen10 Посмотреть сообщение
Только вот не верно, что они потом выводятся в соответствии с кодировкой консоли. Они выводятся точно те же, что и были записаны на этапе компиляции,
Что здесь означает слово "они"? Символы, или байты, или что-то ещё?

Добавлено через 2 часа 21 минуту
Я запутался окончательно.
0
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
25.12.2018, 21:06 19

Не по теме:

Цитата Сообщение от valen10 Посмотреть сообщение
Почитайте еще про Unicode
Я же выше на эту же статью дал ссылку :)



Добавлено через 13 минут
Вопросы автора похожи на вопросы человека открывшего книгу с середины.
Цитата Сообщение от Jzx Посмотреть сообщение
По каким правилам? Каким способом?
В соответствии с кодовой страницей для кодировки, в которой записан файл и которую понимает компилятор. Также для wchar_t сначала применяется преобразование "предпочитаемая кодировка файла"->utf-16 или "предпочитаемая кодировка файла"->utf-32, в зависимости от принятой для wchar_t кодировки (это зависит от ОС, в Linux - wchar_t традиционно хранит UTF-32, в Windows - UTF-16).
"предпочитаемая кодировка файла" - это такая кодировка, в которой компилятор ожидает увидеть символы литералов. Например для GCC - это UTF-8. Для VC++ - это локальная кодировка системы (т.е. CP1251 для русской локализации Windows). Предпочитаемая кодировка как правило может быть изменена соответствующими ключами компилятора. В любом случае результатом будет некий набор байт. Символ - это лишь графическое представление для пользователя, не более того.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
25.12.2018, 21:07  [ТС] 20
Цитата Сообщение от DrOffset Посмотреть сообщение
Вопросы автора похожи на вопросы человека открывшего книгу с середины.
Какую книгу по C++ вы можете рекомендовать, чтобы в ней эти вопросы были подробно разобраны?
0
25.12.2018, 21:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.12.2018, 21:07
Помогаю со студенческими работами здесь

Пользовательские литералы
я тут почитал вот эту статейку, сначала чуть-чуть выпал в осадок, потом немножко охренел, потом...

Строковые литералы. Ошибки
Почему в этой программе ошибки? Если префиксы u и U убрать, то программа все равно не компилируется...

К какому типу принадлежат указанные литералы?
помогите с тестом. 5)Баллов: 1 К какому типу принадлежат следующие литералы 27L 3.6F 'z' 0x27 2u...

Строковые литералы, не пойму как реализовать
В произвольно взятом предложении вывести на экран все слова, начинающиеся на гласную букву.

Разбить строку на литералы и записать их в двумерный массив
Правильно выводит только первый литерал. Все остальные - пустые строки,похоже, поскольку ничего не...

Можно ли сравнивать строковые литералы? как правильно это сделать?
надо сравнить введенный строковый литерал с одним из доступных. int main() { setlocale(0,&quot;&quot;); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru