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

Тип переменной char

19.02.2020, 21:59. Показов 5197. Ответов 55
Метки c++ (Все метки)

Author24 — интернет-сервис помощи студентам
Объясните мне, что то я не понимаю, как я понял, этот тип общий, можно как писать, так вводить цифры, но почему то начиная с 10 программа выключается, также можно писать всего одну букву, но при этом даже русскую. Объясните мне, что из себя представляет этот тип. Я не могу понять, это такой тип который служит для ввода одного любого символа?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.02.2020, 21:59
Ответы с готовыми решениями:

Восьмибитный тип переменной (что за тип, но не BYTE и не CHAR?
Вроде давно занимаюсь программированием на С++, но встала проблема... Есть некий массив переменных...

Определять тип вводимой переменной (char или int)
Вообщем изначально дали задание определять тип вводимой переменной (char или int ). Это я...

Как присвоить к новой char переменной другую char переменную с указателем
Как присвоить к новой char переменной другую char переменную с указателем #include<iostream>...

Не могу преобразовать тип char в тип double
Вся загвоздка в str1 и str2; #include "stdafx.h" #include "conio.h" #include"stdlib.h"...

55
Параллельный Кот
 Аватар для valen10
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
20.02.2020, 01:34 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от elenayagubova Посмотреть сообщение
Нельзя в переменную типа char записать число, введенное пользователем с клавиатуры
Тип переменной char

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
29
#include <iostream>
#include <limits>
 
std::istream& operator>> (std::istream &s, signed char &c) {
    short t;
    s >> t;
    c = (t < std::numeric_limits<char>::min()
         ? std::numeric_limits<char>::min()
         : (t > std::numeric_limits<char>::max()
            ? std::numeric_limits<char>::max()
            : static_cast<char>(t)));
 
    return s;
}
 
std::ostream& operator<< (std::ostream &s, signed char c) {
    s << static_cast<short>(c);
    return s;
}
 
int main() {
    using namespace std;
 
    signed char ch;
    cin >> ch;
    cout << ch << endl;
 
    return 0;
}
0
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
20.02.2020, 01:55 22
valen10, хотела ведь дополнить эту фразу условиями(без перегрузок и т.п.), но не стала. Фактически ввод здесь идёт в переменную short, а не char, и конкретно в этой теме, мне кажется, ТС важнее понять, что при вводе в char 10 вводится не как число, а как два отдельных символа.
0
 Аватар для COKPOWEHEU
4029 / 2575 / 430
Регистрация: 09.09.2017
Сообщений: 11,494
20.02.2020, 08:24 23
Цитата Сообщение от elenayagubova Посмотреть сообщение
Нельзя в переменную типа char записать число, введенное пользователем с клавиатуры
А что мешает?
C
1
2
3
4
  unsigned char ch; //не везде к сожалению char беззнаковый
  scanf("%hhi", &ch);
  int i = ch; //чтобы вывод был нагляднее
  printf("%i\n", i);
Код
$ gcc main.c
$ ./a.out 
10
10
Просто надо понимать, что char - такой же числовой тип, как int, long и т.д. Просто ему соглашением предписан смысл хранить символы. Соответственно многие функции обрабатывают char именно как символьный тип. Но это вопрос соглашения, а не внутреннего представления.
0
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
20.02.2020, 10:27 24
COKPOWEHEU, я выше уже написала, что напрасно не дописала в своей фразе "нельзя без ...", но речь шла о том, что при вводе-выводе тип char является символом, а не числом. Я не думаю, что если бы ТС перегрузил оператор ввода или использовал преобразование к short/int, у него бы возникли те вопросы, которые возникли. Поэтому я акцентировала внимание на том, что в char вводится символ, цифра, а не число, состоящее из нескольких цифр. И при вводе в char как в char будет введен именно символ, а не число, представляющее собой его код.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Просто ему соглашением предписан смысл хранить символы.
Я бы не сказала, что на начальном этапе нужно отмести этот факт как несущественный и сразу пытаться вводить число в char из потока ввода.
0
 Аватар для Annemesski
2618 / 1286 / 472
Регистрация: 08.11.2016
Сообщений: 3,551
20.02.2020, 10:46 25
elenayagubova,
Нельзя в переменную типа char записать число, введенное пользователем с клавиатуры
хотела ведь дополнить эту фразу условиями(без перегрузок и т.п.), но не стала.
C++
1
2
3
char c;
cin >> *(int*)&c;
cout << (int)c;
Без смс и регистрации. В целом, отбросив всякие заумности, вполне законно относиться к типу char как к однобайтовому int, собственно суть чара в том, что это байт и есть, практически собственной персоной.
0
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
20.02.2020, 10:57 26
Annemesski, не без смс и регистрации. Преобразование типа - такие же смс и регистрация. Использовать потоковый ввод(без перегрузок и преобразований типа!) в char и относится к нему как к однобайтовому int, вводя число - незаконно.
0
Неэпический
 Аватар для Croessmah
18116 / 10702 / 2063
Регистрация: 27.09.2012
Сообщений: 26,958
Записей в блоге: 1
20.02.2020, 11:56 27
elenayagubova, char - целочисленный тип размером в один байт. Также он относится к обычным символьным типам. И из потоков читаются байты. При вводе 10, в поток попадают коды символов 1 и 0, и в char запихивается код символа 1, а не машинное представление числа 10, и это заслуга системы ввода-вывода, а не какой-то char'овской магии. В потоках вам сразу подаются коды символов, так что если читать в int, то сначала всё равно читается текст и потом уже конвертируется в машинное представлении числа. Было бы странно, если бы вас заставляли вводить коды символов и машинное представление числа, вместо "человеческих загагулин". Точно также char используется для работы с байтами. На unsigned char также основаны std::byte и char8_t. Всё поведение, видимое при работе с ним как с символом - это не из-за его символьности, а из-за интерпретации хранящегося в нем значения как кода символа (или его части). И, если ввести в кодировке utf-8 в вводной поток символ кириллицы, то символ кириллицы не получится в char, потому что char - это лишь первый байт в представлении символа. Если посмотрите интерфейс стандартных потоков ввода-вывода (iostream), то увидите, что данные там читаются в char. Удивительно, бинарные данные и текстовый буфер! Увы, но char используется для работы с байтами и памятью с самых древних времен, когда еще даже указатели на void не изобрели.
0
 Аватар для Annemesski
2618 / 1286 / 472
Регистрация: 08.11.2016
Сообщений: 3,551
20.02.2020, 11:58 28
elenayagubova, почему? Ведь нет на самом деле никаких символов - это лишь вопрос интерпретации данных который целиком и полностью в ведении программиста, в char лежит число, хотите чтобы это был: октет IP-адреса, код символа в той или иной однобайтовой кодировке (к стати какую кодировку вы предпочитаете?), число (одно из 256 вариантов), интенсивность красного, зеленого или синего в rgb-color - пожалуйста, для всего этого используется тип char и то, что потоковый ввод вывод для char определен разработчиками как символьный ничего не значит, ведь они его сами и перегрузили для char, а по сути iostream - это тоже поток байт. А по Вашей логике и int не int с точки зрения потоков в/в.
0
63 / 46 / 11
Регистрация: 27.12.2017
Сообщений: 1,484
20.02.2020, 12:45 29
Croessmah, я вот к примеру введу 48 в int, каким образом символьное 48 станет численным?
0
129 / 1 / 1
Регистрация: 16.12.2019
Сообщений: 33
20.02.2020, 12:59 30
Кинь свой код, чего он у тебя вылетает интересно.
0
Неэпический
 Аватар для Croessmah
18116 / 10702 / 2063
Регистрация: 27.09.2012
Сообщений: 26,958
Записей в блоге: 1
20.02.2020, 14:12 31
Цитата Сообщение от ReYalp Посмотреть сообщение
каким образом символьное 48 станет численным?
Библиотека всё сделает за вас.
Без учета возможных переполнений и тому подобного:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <cctype>
 
bool input_int(FILE * f, int & result)
{
    int value = 0;
    int cur = EOF;
    bool negative = false;
    do {
        cur = fgetc(f);
    } while (isspace(cur));
    
    negative = (cur == '-');
    if (negative || (cur == '+')) {
        cur = fgetc(f);
    }
    
    if (!isdigit(cur)) {
        ungetc(cur, f);
        return false;
    }
    
    do {
        value = 10 * value + (cur - '0');
    } while ((cur = fgetc(f)) != EOF && isdigit(cur));
    ungetc(cur, f);
    result = value;
    if (negative) {
        result *= -1;
    }
    return true;
}
 
 
int main()
{
    int v1 = 0;
    if (input_int(stdin, v1)) {
        std::cout << v1 << "\n";
    } else {
        std::cout << "input error\n" << INT_MAX;
    }
}
0
 Аватар для COKPOWEHEU
4029 / 2575 / 430
Регистрация: 09.09.2017
Сообщений: 11,494
20.02.2020, 15:55 32
Цитата Сообщение от elenayagubova Посмотреть сообщение
И при вводе в char как в char будет введен именно символ, а не число, представляющее собой его код.
Вы хоть поняли что написали? Символ это и есть его код. И храниться этот код будет именно в двоичном представлении.
Цитата Сообщение от elenayagubova Посмотреть сообщение
речь шла о том, что при вводе-выводе тип char является символом, а не числом.
Вы же видели мой код. Вводится именно char. В него попадает именно число, а не код символа. Никаких перегрузок или преобразований.
Цитата Сообщение от Annemesski Посмотреть сообщение
char c;
cin >> *(int*)&c;
cout << (int)c;
А компилятор с ума не сойдет от таких преобразований?
Проверил: действительно сойдет:
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <iostream>
 
int main(int argc, char **argv){
  char a = 100;
  char b = 50;
  char c = 42;
  printf("%hhi %hhi %hhi\n", a, b, c);
  std::cin >> *(int*)&b;
  printf("%hhi %hhi %hhi\n", a, b, c);
}
Код
$ g++ main.c -Wall
$ ./a.out 
100 50 42
123
0 123 0
Самое забавное, что ваш код портит переменные по обе стороны от целевой. Я думал, только с одной будет. Но выравнивание - штука страшная.
Цитата Сообщение от Croessmah Посмотреть сообщение
На unsigned char также основаны std::byte и char8_t.
Что такое char8_t? Может, uint8_t?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.02.2020, 15:59 33
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что такое char8_t? Может, uint8_t?
Цитата Сообщение от http://eel.is/c++draft/basic.fundamental#9
Type char8_­t denotes a distinct type whose underlying type is unsigned char. Types char16_­t and char32_­t denote distinct types whose underlying types are uint_­least16_­t and uint_­least32_­t, respectively, in <cstdint> ([cstdint.syn]).
C++20
0
 Аватар для COKPOWEHEU
4029 / 2575 / 430
Регистрация: 09.09.2017
Сообщений: 11,494
20.02.2020, 16:57 34
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++20
В С11 такого нет.
0
Неэпический
 Аватар для Croessmah
18116 / 10702 / 2063
Регистрация: 27.09.2012
Сообщений: 26,958
Записей в блоге: 1
20.02.2020, 17:10 35
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что такое char8_t? Может, uint8_t?
Нет. Тип char8_t введен в C++20.
Зачем это нужно: https://youtu.be/g2iyNH2Gh1k?t=1233
1
 Аватар для COKPOWEHEU
4029 / 2575 / 430
Регистрация: 09.09.2017
Сообщений: 11,494
20.02.2020, 18:40 36
Цитата Сообщение от Croessmah Посмотреть сообщение
Зачем это нужно
и зачем же? Там лектор привел какой-то пример и предположения об оптимизациях компилятора. Разница для компилятора между uint8_t и uint8_t не раскрыта. Единственное предположение, которое у меня возникло - компилятор может пытаться трактовать char* как строку или даже как форматную строку. Но это опять же проблема компилятора, а не языка.
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.02.2020, 18:51 37
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Разница для компилятора между uint8_t и uint8_t не раскрыта.
Ну uint8_t и uint8_t точно одинаковы.

Мотивация для char8_t:
Чтобы обеспечить отдельный тип для символьных данных UTF-8 по сравнению с символьными данными с кодировкой, которая либо зависит от локали, либо требует отдельной спецификации.
Чтобы разрешить перегрузку для обычных строковых литералов и строковых литералов UTF-8 (поскольку они могут иметь разные кодировки).
Для обеспечения типа без знака для данных UTF-8 (независимо от того, является ли символ подписанным или неподписанным, определяется реализацией).
Чтобы обеспечить лучшую производительность via a non-aliasing types.
0
Неэпический
 Аватар для Croessmah
18116 / 10702 / 2063
Регистрация: 27.09.2012
Сообщений: 26,958
Записей в блоге: 1
20.02.2020, 18:51 38
COKPOWEHEU, вы знаете о strict aliasing?
0
 Аватар для COKPOWEHEU
4029 / 2575 / 430
Регистрация: 09.09.2017
Сообщений: 11,494
20.02.2020, 19:38 39
Цитата Сообщение от Azazel-San Посмотреть сообщение
Чтобы обеспечить отдельный тип для символьных данных UTF-8 по сравнению с символьными данными с кодировкой, которая либо зависит от локали, либо требует отдельной спецификации.
Чем оно лучше текущей реализации utf-8 на обычных char'ах? Нет, я согласен, что библиотечных функций для этого сейчас маловато, но, видимо, сложности самого utf-8.
Цитата Сообщение от Azazel-San Посмотреть сообщение
Чтобы разрешить перегрузку для обычных строковых литералов и строковых литералов UTF-8 (поскольку они могут иметь разные кодировки).
На первый взгляд это имеет смысл... но если подумать - все равно же кодировка задается функцией setlocale, а потом консоль те же самые байты трактует как нужно. Чем тут поможет перегрузка?
Цитата Сообщение от Azazel-San Посмотреть сообщение
Для обеспечения типа без знака для данных UTF-8 (независимо от того, является ли символ подписанным или неподписанным, определяется реализацией).
Так проще char сделать беззнаковым по умолчанию. Кому надо сделают знаковым. Оно же и сейчас почти так.
Про "подписанные символы" не слышал такого термина. Первая страница гугла тоже молчит.
Цитата Сообщение от Azazel-San Посмотреть сообщение
Чтобы обеспечить лучшую производительность via a non-aliasing types.
Какое выравнивание переменных размером в один байт? Или я как-то не так понимаю термин aliasing?
0
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
20.02.2020, 19:54 40
Croessmah, с тем, что char - целочисленный тип и всем из этого следующим, я нигде и не спорила(что было бы, несомненно, очень глупо). Изначально я только писала о вводе и о том, что нельзя считать char в этом случае обычным числом - вводится символ. 10 - не символ. При вводе 10 в переменную char запишется код 1, а код 0 останется в потоке. Это не единое число, а два отдельных символа. А вот при вводе 10 в int, оба символа интерпретируются как единое число.


Annemesski,
Цитата Сообщение от Annemesski Посмотреть сообщение
и то, что потоковый ввод вывод для char определен разработчиками как символьный ничего не значит
Если у меня в коде есть строки char ch; cin >> ch;, очень даже значит. Я обязана понимать, что при вводе 10 в ch будет записан код символа '1', а не число 10. А это все, что я пыталась сказать в своем изначальном сообщении - не больше и меньше.

COKPOWEHEU,
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы хоть поняли что написали?
Вероятно, я плохо сформулировала мысль. Речь идет о том, что при вводе "10" в переменную попадет символ '1'(в виде своего кода), а не число 10, которое тоже является кодом какого-то символа.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы же видели мой код. Вводится именно char. В него попадает именно число, а не код символа. Никаких перегрузок или преобразований.
Да, здесь согласна, мне нужно было уточнить, что речь именно про изначальную строку cin >> ch; В этом примере я бы то же самое говорила при использовании спецификатора %c - нельзя получить с его помощью число, введенное с клавиатуры.
0
20.02.2020, 19:54
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.02.2020, 19:54
Помогаю со студенческими работами здесь

Почему в setnamedisc нужно использовать char * для установки значения, а при возвращении значения тип метода должен быть char* ?
Вопрос такой, почему в методе setnamedisc нужно использовать char *s для установки значения, а при...

Присвоить переменной char m значиние переменной int i..
Как присвоить переменной char m значиние переменной int i таким образом ? int main() { char...

тип char
Подскажите плз, почему сортировка не работает с типом char. С типом int, элементы сортируются. ...

Тип char и указатели
Вопрос... Тип может хранить только символы, или строки тоже? Если только символы, то почему этот...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Информационные технологии
hw_wired 28.01.2025
Введение в современные технологии работы с информацией В современном мире информационные технологии стали неотъемлемой частью практически всех сфер человеческой деятельности. Они существенно. . .
Информация вокруг нас
hw_wired 28.01.2025
Основные понятия информации В современном мире понятие информации является фундаментальным и охватывает практически все сферы человеческой деятельности. Информация представляет собой совокупность. . .
Компьютер для начинающих
hw_wired 28.01.2025
Введение в мир компьютерных технологий В современном мире информация стала одним из важнейших ресурсов человечества, определяющим развитие общества и технологий. Наша жизнь неразрывно связана с. . .
[golang] 189. Rotate Array
alhaos 28.01.2025
Повороты рукоятки, целочисленный слайс нужно сдвинуть на целое положительное число. Мне очень нравится решение на GO / / https:/ / leetcode. com/ studyplan/ top-interview-150/ package topInterview . . .
КуМир: решение задач на матрицы
bytestream 28.01.2025
КуМир представляет собой среду для обучения программированию, которая включает в себя мощные инструменты для работы с матрицами. Матрица в программировании - это двумерный массив, состоящий из. . .
КуМир: решение задач на строки
bytestream 28.01.2025
В системе программирования КуМир работа со строковыми данными является одним из важнейших аспектов создания программ. Строки представляют собой последовательности символов, заключенные в кавычки,. . .
КуМир: решение геометрических задач
bytestream 28.01.2025
Программирование геометрических задач в среде КуМир становится всё более актуальным в обучении школьников и студентов. КуМир — это разработанная в России обучающая программная среда, предназначенная. . .
КуМир, исполнитель Водолей: Задачи и решения
bytestream 28.01.2025
КуМир — это образовательная среда для обучения программированию. Она предлагает пользователям разнообразные инструменты для разработки и отладки программ, что особенно ценно для студентов и. . .
КуМир, исполнитель Чертежник: Решение задач
bytestream 28.01.2025
КуМир (Комплект Учебных МИРов) представляет собой образовательную среду для обучения основам программирования и алгоритмизации. Исполнитель Чертежник работает на координатной плоскости, где может. . .
Rust или Go? А может C++?
hw_wired 28.01.2025
С каждой новой технологией или методологией появляются новые языки программирования, призванные решать конкретные задачи либо улучшать аспекты производительности и безопасности. Среди множества. . .
Fortran и WinAPI: как создать приложение с графическим интерфейсом
hw_wired 28.01.2025
Fortran — это один из старейших высокоуровневых языков программирования, широко используемый в науке и инженерии уже несколько десятилетий. Его название происходит от "Formula Translation" (перевод. . .
Списки в Haskell
hw_wired 28.01.2025
Haskell является функциональным языком программирования, который отличается лаконичностью синтаксиса и мощными абстракциями. Важным концептом в Haskell являются списки — упорядоченные коллекции. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru