какое максимальное количество символов может хранить переменная типа char
Урок №35. Символьный тип данных char
Обновл. 11 Сен 2021 |
Хоть тип char и относится к целочисленным типам данных (и, таким образом, следует всем их правилам), работа с char несколько отличается от работы с обычными целочисленными типами.
Тип данных char
Переменная типа char занимает 1 байт. Однако вместо конвертации значения типа char в целое число, оно интерпретируется как ASCII-символ.
ASCII (сокр. от «American Standard Code for Information Interchange») — это американский стандартный код для обмена информацией, который определяет способ представления символов английского языка (+ несколько других) в виде чисел от 0 до 127. Например: код буквы ‘а’ — 97, код буквы ‘b’ — 98. Символы всегда помещаются в одинарные кавычки.
Таблица ASCII-символов:
Код | Символ | Код | Символ | Код | Символ | Код | Символ |
0 | NUL (null) | 32 | (space) | 64 | @ | 96 | ` |
1 | SOH (start of header) | 33 | ! | 65 | A | 97 | a |
2 | STX (start of text) | 34 | ” | 66 | B | 98 | b |
3 | ETX (end of text) | 35 | # | 67 | C | 99 | c |
4 | EOT (end of transmission) | 36 | $ | 68 | D | 100 | d |
5 | ENQ (enquiry) | 37 | % | 69 | E | 101 | e |
6 | ACK (acknowledge) | 38 | & | 70 | F | 102 | f |
7 | BEL (bell) | 39 | ’ | 71 | G | 103 | g |
8 | BS (backspace) | 40 | ( | 72 | H | 104 | h |
9 | HT (horizontal tab) | 41 | ) | 73 | I | 105 | i |
10 | LF (line feed/new line) | 42 | * | 74 | J | 106 | j |
11 | VT (vertical tab) | 43 | + | 75 | K | 107 | k |
12 | FF (form feed / new page) | 44 | , | 76 | L | 108 | l |
13 | CR (carriage return) | 45 | — | 77 | M | 109 | m |
14 | SO (shift out) | 46 | . | 78 | N | 110 | n |
15 | SI (shift in) | 47 | / | 79 | O | 111 | o |
16 | DLE (data link escape) | 48 | 0 | 80 | P | 112 | p |
17 | DC1 (data control 1) | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 (data control 2) | 50 | 2 | 82 | R | 114 | r |
19 | DC3 (data control 3) | 51 | 3 | 83 | S | 115 | s |
20 | DC4 (data control 4) | 52 | 4 | 84 | T | 116 | t |
21 | NAK (negative acknowledge) | 53 | 5 | 85 | U | 117 | u |
22 | SYN (synchronous idle) | 54 | 6 | 86 | V | 118 | v |
23 | ETB (end of transmission block) | 55 | 7 | 87 | W | 119 | w |
24 | CAN (cancel) | 56 | 8 | 88 | X | 120 | x |
25 | EM (end of medium) | 57 | 9 | 89 | Y | 121 | y |
26 | SUB (substitute) | 58 | : | 90 | Z | 122 | z |
27 | ESC (escape) | 59 | ; | 91 | [ | 123 | < |
28 | FS (file separator) | 60 | 94 | ^ | 126 | ||
31 | US (unit separator) | 63 | ? | 95 | _ | 127 | DEL (delete) |
Символы от 0 до 31 в основном используются для форматирования вывода. Большинство из них уже устарели.
Символы от 32 до 127 используются для вывода. Это буквы, цифры, знаки препинания, которые большинство компьютеров использует для отображения текста (на английском языке).
Следующие два стейтмента выполняют одно и то же (присваивают переменным типа char целое число 97 ):
Будьте внимательны при использовании фактических чисел с числами, которые используются для представления символов (из ASCII-таблицы). Следующие два стейтмента выполняют не одно и то же:
Вывод символов
При выводе переменных типа char, объект cout выводит символы вместо цифр:
Также вы можете выводить литералы типа char напрямую:
Оператор static_cast
Если вы хотите вывести символы в виде цифр, а не в виде букв, то вам нужно сообщить cout выводить переменные типа char в виде целочисленных значений. Не очень хороший способ это сделать — присвоить переменной типа int переменную типа char и вывести её:
Лучшим способом является конвертация переменной из одного типа данных в другой с помощью оператора static_cast.
Синтаксис static_cast выглядит следующим образом:
Пример использования оператора static_cast для конвертации типа char в тип int:
Результат выполнения программы:
Также в static_cast нет никакой проверки по диапазону, так что если вы попытаетесь использовать числа, которые будут слишком большие или слишком маленькие для конвертируемого типа, то произойдет переполнение.
Более подробно о static_cast мы еще поговорим на соответствующем уроке.
Ввод символов
Следующая программа просит пользователя ввести символ. Затем она выводит этот символ и его ASCII-код:
Результат выполнения программы:
Input a keyboard character: q
q has ASCII code 113
Обратите внимание, даже если cin позволит вам ввести несколько символов, переменная ch будет хранить только первый символ (именно он и помещается в переменную). Остальная часть пользовательского ввода останется во входном буфере, который использует cin, и будет доступна для использования последующим вызовам cin.
Рассмотрим это всё на практике:
Результат выполнения программы:
Input a keyboard character: abcd
a has ASCII code 97
b has ASCII code 98
Размер, диапазон и знак типа сhar
В языке С++ для переменных типа char всегда выделяется 1 байт. По умолчанию, char может быть как signed, так и unsigned (хотя обычно signed). Если вы используете char для хранения ASCII-символов, то вам не нужно указывать знак переменной (поскольку signed и unsigned могут содержать значения от 0 до 127).
Управляющие символы
В языке C++ есть управляющие символы (или «escape-последовательности»). Они начинаются с бэкслеша ( \ ), а затем следует определенная буква или цифра.
First line
Second line
First part Second part
Таблица всех управляющих символов в языке C++:
Название | Символ | Значение |
Предупреждение (alert) | \a | Предупреждение (звуковой сигнал) |
Backspace | \b | Перемещение курсора на одну позицию назад |
formfeed | \f | Перемещение курсора к следующей логической странице |
Символ новой строки (newline) | \n | Перемещение курсора на следующую строку |
Возврат каретки (carriage return) | \r | Перемещение курсора в начало строки |
Горизонтальный таб (horizontal tab) | \t | Вставка горизонтального TAB |
Вертикальный таб (vertical tab) | \v | Вставка вертикального TAB |
Одинарная кавычка | \’ | Вставка одинарной кавычки (или апострофа) |
Двойная кавычка | \” | Вставка двойной кавычки |
Бэкслеш | \\ | Вставка обратной косой черты (бэкслеша) |
Вопросительный знак | \? | Вставка знака вопроса |
Восьмеричное число | \(number) | Перевод числа из восьмеричной системы счисления в тип char |
Шестнадцатеричное число | \x(number) | Перевод числа из шестнадцатеричной системы счисления в тип char |
Рассмотрим пример в коде:
Результат выполнения программы:
«This is quoted text»
This string contains a single backslash \
6F in hex is char ‘o’
Что использовать: ‘\n’ или std::endl?
При использовании std::cout, данные для вывода могут помещаться в буфер, т.е. std::cout может не отправлять данные сразу же на вывод. Вместо этого он может оставить их при себе на некоторое время (в целях улучшения производительности).
Используйте \n во всех остальных случаях.
Другие символьные типы: wchar_t, char16_t и char32_t
Тип wchar_t следует избегать практически во всех случаях (кроме тех, когда происходит взаимодействие с Windows API).
Так же, как и стандарт ASCII использует целые числа для представления символов английского языка, так и другие кодировки используют целые числа для представления символов других языков. Наиболее известный стандарт (после ASCII) — Unicode, который имеет в запасе более 110 000 целых чисел для представления символов из разных языков.
Существуют следующие кодировки Unicode:
UTF-32 — требует 32 бита для представления символа.
UTF-16 — требует 16 бит для представления символа.
UTF-8 — требует 8 бит для представления символа.
Типы char16_t и char32_t были добавлены в C++11 для поддержки 16-битных и 32-битных символов Unicode (8-битные символы и так поддерживаются типом char).
В чём разница между одинарными и двойными кавычками при использовании с символами?
Текст, который находится в двойных кавычках, называется строкой (например, «Hello, world!» ). Строка (тип string) — это набор последовательных символов.
Вы можете использовать литералы типа string в коде:
Более подробно о типе string мы поговорим на соответствующем уроке.
Поделиться в социальных сетях:
Урок №34. Логический тип данных bool
Комментариев: 12
>>Тип wchar_t следует избегать практически во всех случаях
Вот за такой совет автора оригинала… Это одна из причин, почему софт сделанный на одном языке крашится на ОС с другим языком — например японская игра на американской винде.. Да и собственно некоторый английский софт на русской винде.
Потому что либо они думают что кроме английского никаких языков нет и юзают char, либо пытаются втулить все в char8_t
В главе №30 «Размер типов данных» было написано «Интересно то, что sizeof — это один из 3-х операторов в языке C++, который является словом, а не символом (еще есть new и delete)». А в этой главе оказывается что есть ещё static_cast
странно, но в с++ sizeof(‘a’) == sizeof(char), в то время как в си — sizeof(‘a’) == sizeof(int). неожиданно …
В Си подобная конструкция sizeof(‘a’) == sizeof(int) имеет место из-за его особенностей. Аргумент первого sizeof скорее всего рассматривается как выражение (expression). А во всех выражениях в Си имеет место приведение к типу int, если используется меньший по размеру тип. Что и имеет место в данном случае. На деле же (насколько я знаю) в Си символы тоже размером в один байт. Вроде бы тип char так и вводился, чтобы быть равным одному байту.
Привет!
Вот с этим не понятно ничего:
Типы char и varchar (Transact-SQL)
Символьные типы данных имеют фиксированный (char) или переменный (varchar) размер. Начиная с SQL Server 2019 (15.x) при использовании параметров сортировки с поддержкой UTF-8 эти типы данных хранят весь диапазон символьных данных Юникод и используют кодировку UTF-8. Если указаны параметры сортировки без поддержки UTF-8, эти типы данных хранят только подмножество символьных данных, поддерживаемых соответствующей кодовой страницей указанных параметров сортировки.
Аргументы
char [ ( n ) ] — строковые данные фиксированного размера. n определяет размер строки в байтах и должно иметь значение от 1 до 8000. Для однобайтовых кодировок, таких как Latin, размер при хранении равен n байт, а количество хранимых символов — тоже n. Для многобайтовых кодировок размер при хранения тоже равен n байт, но количество хранимых символов может быть меньше n. Синонимом по стандарту ISO для типа char является character. Дополнительные сведения о кодировках см. в статье Однобайтовые и многобайтовые кодировки.
varchar [ ( n | max ) ] — строковые данные переменного размера. Используйте значение n для определения размера строки в байтах (допускаются значения от 1 до 8000) или используйте max для указания предельного размера столбца вплоть до максимального размера хранилища, что составляет 2^31-1 байт (2 ГБ). Для однобайтовых кодировок, таких как Latin, размер при хранении равен n байт + 2 байта, а количество хранимых символов — n. Для многобайтовых кодировок размер при хранении тоже равен n байт + 2 байта, но количество хранимых символов может быть меньше n. Синонимами по стандарту ISO для типа varchar являются типы charvarying или charactervarying. Дополнительные сведения о кодировках см. в статье Однобайтовые и многобайтовые кодировки.
Remarks
Часто ошибочно считают, что в типах данных CHAR(n) и VARCHAR(n) число n указывает на количество символов. Однако на самом деле число n в CHAR(n) и VARCHAR(n) — это длина строки в байтах (0–8000). n никогда не определяет количество хранимых символов. То же самое верно и в отношении типов NCHAR(n) и NVARCHAR(n). Причина этого заблуждения в том, что при использовании однобайтовых кодировок размер данных типов CHAR и VARCHAR при хранении равен n байт, а количество символов — тоже n. Однако в случае с многобайтовыми кодировками, такими как UTF-8, в старших диапазонах Юникода (128–1 114 111) один символ занимает два или несколько байтов. Например, в столбце, определенном как CHAR(10), Компонент Database Engine может хранить 10 символов, использующих однобайтовую кодировку (диапазон Юникода 0–127), но меньше 10 символов при использовании многобайтовой кодировки (диапазон Юникода 128–1 114 111). Дополнительные сведения о хранении символов Юникода и их диапазонах см. в разделе Различия в хранении UTF-8 и UTF-16.
Если значение n в определении данных или инструкции объявления переменной не указано, длина по умолчанию равна 1. Если значение n не указано при использовании функций CAST и CONVERT, длина по умолчанию равна 30.
Объектам, в которых используются типы данных char и varchar, назначаются параметры сортировки базы данных по умолчанию, если только иные параметры сортировки не назначены с использованием предложения COLLATE. Параметры сортировки контролируют кодовую страницу, используемую для хранения символьных данных.
В SQL Server многобайтовые кодировки включают:
Если у вас есть сайты, поддерживающие несколько языков, примите к сведению следующие рекомендации:
Если вы используете char или varchar, мы рекомендуем:
Если SET ANSI_PADDING равно OFF при выполнении CREATE TABLE или ALTER TABLE, столбец char, определенный как NULL, обрабатывается как varchar.
Для каждого ненулевого столбца varchar(max) или nvarchar(max) требуется 24 байта дополнительного фиксированного выделения, которые учитываются в максимальном размере строки в 8060 байт во время операции сортировки. Это может создать неявное ограничение в ряде ненулевых столбцов varchar(max) или nvarchar(max), которые могут быть созданы в таблице. При создании таблицы или во время вставки данных не возникает особых ошибок (кроме обычного предупреждения о том, что максимальный размер строки превышает максимально допустимое значение в 8060 байт). Такой размер строки может вызывать ошибки (например, ошибку 512) во время некоторых обычных операций, таких как обновление ключа кластеризованного индекса, или сортировки полного набора столбцов, которая происходит только во время выполнения операции.
Преобразование символьных данных
При преобразовании символьного выражения в символьный тип данных другой длины значения, слишком длинные для нового типа данных, усекаются. Тип uniqueidentifier считается символьным типом, используемым при преобразовании из символьного выражения, поэтому на него распространяются правила усечения при преобразовании в символьный тип. См подраздел «Примеры» ниже.
Преобразование кодовых страниц поддерживается для типов данных char и varchar, однако поддержка типа данных text не предусмотрена. Как и в ранних версиях SQL Server, о потере данных во время преобразования кодовых страниц не сообщается.
Символьные выражения, которые преобразуются в приближенный тип данных numeric, могут содержать необязательную экспоненциальную нотацию (символ e нижнего регистра или E верхнего регистра, за которым следуют необязательный знак плюс (+) или минус (–) и число).
Символьные выражения, преобразуемые в точный тип данных numeric, должны состоять из цифр, десятичного разделителя и необязательного знака плюс (+) или минус (–). Начальные пробелы не учитываются. Разделители в виде запятой запрещены (например, десятичный разделитель в числе 123 456,00).
Кроме того, символьные выражения, преобразуемые в типы данных money или smallmoney, могут содержать необязательный десятичный разделитель и обозначение валюты. Разрешаются разделители в виде запятой, например 123 456,00 руб.
Примеры
A. Отображение значения по умолчанию n при использовании в объявлении переменной
Б. Отображение значения по умолчанию n при использовании функций CAST и CONVERT с типом данных varchar
В. Преобразование данных для отображения
В следующем примере два столбца преобразуются в символьные типы, после чего к ним применяется стиль, применяющий к отображаемым данным конкретный формат. Тип money преобразуется в символьные данные. К нему применяется стиль 1, отображающий значения с запятыми между каждой группой из трех цифр, отсчитывая влево от десятичной точи, и каждой группой из двух цифр, отсчитывая вправо от десятичной точки. Тип datetime преобразуется в символьные данные. К нему применяется стиль 3, отображающий данные в формате дд/мм/гг. В предложении WHERE тип money приводится к символьному типу для выполнения операции сравнения строк.
Г. Преобразование данных uniqueidentifier
Следующий пример показывает усечение данных, когда значение является слишком длинным для преобразования в заданный тип данных. Так как тип данных uniqueidentifier ограничен 36 символами, все символы, выходящие за пределы этой длины, будут усечены.
Переменные
Переменные
П еременные используются для хранения значений (sic!). Переменная характеризуется типом и именем. Начнём с имени. В си переменная может начинаться с подчерка или буквы, но не с числа. Переменная может включать в себя символы английского алфавита, цифры и знак подчёркивания. Переменная не должна совпадать с ключевыми словами (это специальные слова, которые используются в качестве управляющих конструкций, для определения типов и т.п.)
auto | double | int | struct |
break | else | long | switch |
register | typedef | char | extern |
return | void | case | float |
unsigned | default | for | signed |
union | do | if | sizeof |
volatile | continue | enum | short | while | inline |
А также ряд других слов, специфичных для данной версии компилятора, например far, near, tiny, huge, asm, asm_ и пр.
Типы переменных
Целые
Указанные выше значения характерны для компилятора VC2012 на 32-разрядной машине. Так что, если ваша программа зависит от размера переменной, не поленитесь узнать её размер.
Тип | Размер, байт | Минимальное значение | Максимальное значение |
---|---|---|---|
unsigned char | 1 | 0 | 255 |
signed char ( char ) | 1 | -128 | 127 |
unsigned short | 2 | 0 | 65535 |
signed short ( short ) | 2 | -32768 | 32767 |
unsigned int ( unsigned ) | 4 | 0 | 4294967296 |
signed int ( int ) | 4 | -2147483648 | 2147483647 |
unsigned long | 4 | 0 | 4294967296 |
signed long ( long ) | 4 | -2147483648 | 2147483647 |
unsigned long long | 8 | 0 | 18446744073709551615 |
signed long long ( long long ) | 8 | -9223372036854775808 | 9223372036854775807 |
sizeof
В си есть оператор, который позволяет получить размер переменной в байтах. sizeof переменная, или sizeof(переменная) или sizeof(тип). Это именно оператор, потому что функция не имеет возможности получить информацию о размере типов во время выполнения приложения. Напишем небольшую программу чтобы удостовериться в размерах переменных.
(Я думаю ясно, что переменные могут иметь любое валидное имя). Эту программу можно было написать и проще
В си один и тот же тип может иметь несколько названий
short === short int
long === long int
long long === long long int
unsigned int === unsigned
Типы с плавающей точкой
Переполнение переменных
Си не следит за переполнением переменных. Это значит, что постоянно увеличивая значение, скажем, переменной типа int в конце концов мы «сбросим значение»
Вообще, поведение при переполнении переменной определено только для типа unsigned: Беззнаковое целое сбросит значение. Для остальных типов может произойти что угодно, и если вам необходимо следить за переполнением, делайте это вручную, проверяя аргументы, либо используйте иные способы, зависящие от компилятора и архитектуры процессора.
Постфиксное обозначение типа
Следующий код, однако, не будет приводить к ошибкам, потому что происходит неявное преобразование типа
Шестнадцатеричный и восьмеричный формат
В о время работы с числами можно использовать шестнадцатеричный и восьмеричный формат представления. Числа в шестнадцатиричной системе счисления начинаются с 0x, в восьмеричной системе с нуля. Соответственно, если число начинается с нуля, то в нём не должно быть цифр выше 7:
Экспоненциальная форма представления чисел
Объявление переменных
При объявлении переменной пишется её тип и имя.
Можно объявить несколько переменных одного типа, разделив имена запятой
Здесь объявлены переменные a и b внутри функции main, и переменная z внутри тела цикла. Следующий код вызовет ошибку компиляции
Это связано с тем, что объявление переменной стоит после оператора присваивания. При объявлении переменных можно их сразу инициализировать.
int i = 0;
При этом инициализация при объявлении переменной не считается за отдельный оператор, поэтому следующий код будет работать
Начальное значение переменной
Область видимости переменной
П еременные бывают локальными (объявленными внутри какой-нибудь функции) и глобальными. Глобальная переменная видна всем функциям, объявленным в данном файле. Локальная переменная ограничена своей областью видимости. Когда я говорю, что переменная «видна в каком-то месте», это означает, что в этом месте она определена и её можно использовать. Например, рассмотрим программу, в которой есть глобальная переменная
Будет выведено
foo: 100
bar: 333
Здесь глобальная переменная global видна всем функциям. Но аргумент функции затирает глобальную переменную, поэтому при передаче аргумента 333 выводится локальное значение 333.
Вот другой пример
Программа выведет 555. Также, как и в прошлом случае, локальная переменная «важнее». Переменная, объявленная в некоторой области видимости не видна вне её, например
Этот пример не скомпилируется, потому что переменная y существует только внутри своего блока.
Вот ещё пример, когда переменные, объявленные внутри блока перекрывают друг друга
Программа выведет
30
20
10
Глобальных переменных необходимо избегать. Очень часто можно услышать такое. Давайте попытаемся разобраться, почему. В ваших простых проектах глобальные переменные выглядят вполне нормально. Но представьте, что у вас приложение, которое
Во-первых, глобальная переменная, если она видна всем, может быть изменена любой частью программы. Вы изменили глобальную переменную, хотите её записать, а другая часть программы уже перезаписала в неё другое значение (на самом деле это целый класс проблем, которые возникают в многопоточной среде). Во-вторых, при больших размерах проекта не уследить, кто и когда насоздавал глобальных переменных. В приведённых выше примерах видно, как переменные могут перекрывать друг друга, то же произойдёт и в крупном проекте.
Безусловно, есть ситуации, когда глобальные переменные упрощают программу, но такие ситуации случаются не часто и не в ваших домашних заданиях, так что НЕ СОЗДАВАЙТЕ ГЛОБАЛЬНЫХ ПЕРЕМЕННЫХ!
Переменные могут быть не только целочисленными и с плавающей точкой. Существует множество других типов, которые мы будем изучать в дальнейшем.