Переменная типа char в C++ для начинающих и как с ней работать

У меня, как начинающего изучение С++, сразу возникли трудности обработки переменной типа char. Самый мой первый вопрос: "А как вывести переменную типа char на экран?".
Несмотря на минимальную потребность: вывести на экран только одну, например, букву, поиск мне выдавал страницы с подробным описанием типа char или с очень мудрёнными кодами.
Сложность у меня возникла из-за того, что я не мог понять, как сохранять отдельный символ в переменную, книг в тот момент у меня не имелось.
Для сохранения переменной типа char используют такой код:

Как вы можете видеть, никакой проблемы, оказывается, и нет. Всё делается очень просто.
Немного объяснений по показанному коду. В этом коде объявлена переменная ch, тип которой есть char. Переменные, имеющие тип char называют символьными переменными. Тут всё логично: тип предназначен для обработки символов, значит все его переменные — символьные переменные. Хотя технически тип char работает с числами: он относится к целочисленным типам, объект cout умеет понимать его как символьный тип. Дальше все переменные типа char я буду называть символьными переменными, чтобы читателю было понятней.
  • Символьная переменная — это числовая переменная, которая используется для представления символов.
Любой отдельный символ, представленный в C++ как char, на самом деле обычное число. Любые операции (сложение, вычитание…), применяемые к обычным целым числам, можно применять к символам char.
Почему C++ выводит число как символ? Это не С++ выводит число как символ, а cout показывает char как символы.

Именно проблема, описываемая в листинге #1, вводила меня в заблуждение, наверняка кого-то вводит ещё. Это характерная ошибка новичков: не указать символьное обозначение сохраняемому значению. Из-за того, что символьные переменные по факту числа, компиляторы С++ никак не противятся сохранению в числовой тип чисел.
  • Чтобы записать в переменную отдельный символ, укутывайте сохраняемый символ в одинарные кавычки.
В С++ одинарные кавычки и двойные кавычки имеют разные предназначения. Одинарные кавычки используют для символов, а двойные кавычки для строк. Это важно.

Бывает, что новичок, плохо знающий основы языка С++, для сохранения в символьную переменную использует код, похожий на вот этот:

Это сработает, но это же жуть. Создаётся видимость сохранения в переменную ch символа 'F', такой код обозначает сохранение первого символа строки "F" в переменную ch. В С++ всегда двойные кавычки обозначают строковое представление, даже один символ, обёрнутый в двойные кавычки, считается строкой.
Пример, демонстрирующий различие:

В моих первых попытках работы с символьной переменной как с обычной переменной моей ошибкой было заключение сохраняемого символа в двойные кавычки:

В один символ не может уместиться настоящая строка, вот и всё объяснение. К тому же строки, заключаемые в исходном коде С++ в двойные кавычки, нельзя просто взять и скопировать в переменную по тем же причинам, что массив нельзя сохранить в переменную.
  • Даже пустая строка в C++ воспринимается компилятором как нечто, содержащее внутри себя много символов, хотя хранится внутри только один символ, признак конца строки

Ошибка происходит из-за разнобоя в типах данных: в char происходит попытка сохранить char[1], компилятор С++ считает, что char[1] слишком большой для char и не даёт возможности такого сохранения.
К сожалению, компиляторы допускают ошибочное написание кодов следующего вида:

В таком коде происходит попытка запихнуть в одинарные кавычки строку, но одинарные кавычки предназначены для обычных символов и некоторых спецсимолов, строки в такие кавычки запихивать не получиться. Результатом работы ошибочного кода будет вывод на экран только последнего символа. Новички могут путаться в виде кавычек, в тем более в некоторых языках программирования разницы между одинарными и двойными не существует.
Поскольку тип char относится к целочисленным типам, компьютер видит переменные типа char как числа, то числа эти можно легко подсмотреть.

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

  • Сохранять символы в переменную типа char.
  • В С++ одинарные кавычки используются для символов, двойные для массивов символов.
  • Для символьных переменных массивы слишком велики.
  • Символьные переменные это обычные числа, ASCII коды, которые могут быть представлены людям в виде символов.
  • То, что мы видим числа как символы, следствие работы объекта cout
  • Числовое представление символьных типов легко получать с помощью несложных манипуляций
  • В символ можно присвоить значение из массива путем вытаскивания из массива элемента по индексу или разыменования первого элемента массива (т. е. вытаскивать и сохранять символ), но не сохранять в символ массив.
Моё описание непосредственно типа char в С++ на этом закончено. Не путайте кавычки.

Немного забегу вперёд, покажу кое-что.
Отдельные символы — это, конечно, хорошо, но наиболее востребована работа со строками. В первых версиях С++ работа со строками велась либо при помощи указателей на массив символов, либо просто массива символов.

Язык С++ является надмножеством языка С, поэтому в первых версиях компиляторов С++ со строками приходилось работать как в С. Отсюда название Си-строки или Си-подобные строки. Указатели и массивы тесно связаны между собой, но это разные сущности. При написании строки, оборачиваемой двойными кавычками непосредственно внутри исходного кода программы, говорят, что такая строка константная строка, т. е. её изменять нельзя.
Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

15 комментариев: Переменная типа char в C++ для начинающих и как с ней работать

  • Anonymous говорит:

    char s1; s1="y"; можно было так: char s1='у';

    Автор сайта отвечает:
    Да. Это проще и правильнее. Спасибо

  • Алексей говорит:

    Спасибо, все понятно описано! Буду читать ваш блог

  • guest говорит:

    char *s1 = «y»;

  • Was говорит:

  • Денис говорит:

    ———
    char s1 [100]; //Объявляем переменную s1
    Почти равносилен тому, что мы объявили строку, состоящую из 101 символа.
    Если не понимаете почему 101, а не 100 – лучше изучайте массивы
    ———

    Что значит «почти»? В объявленном массиве 100 элементов, а не 101. «Лучше изучайте массивы» 🙂

    Автор сайта отвечает:
    Ошибся, когда писал. Что ж поделать,
    Трудно что-то исправлять когда сотни тысяч глаз глаз видят страницу, читают её, учат по ней и только спустя годы кто-то говорит, что тут вот ошибка.

    спасибо, что отметили ошибку.

  • Infinity говорит:

    Когда ты пишешь char s1=»y», то ты присваиваешь переменной типа символ строку! Так как двойные ковычки — это строка, это передача значание y и символа конца строки. Поэтому у тебя и не присваивалось значение.
    А с * у тебя получилось, так как ты присвоил переменной типа чар первый элемент массива.
    Правильно надо было присвоить переменной типа чар только символ, а для этого символ помещается в ОДИНАРНЫЕ кавычки.
    s1=’y’;

    Автор сайта отвечает:
    именно так.
    только один нюанс. В С++ тип char это обычные целые числа. Только в отличии от привычных целочисленных типов данных, он используется для представления символов. Т.е. также правильно как и с одинарными кавычками присваивать в переменную s целое число, которое соответствует нужному символу.

    Максим говорит:
    06.01.2014 в 6:57 пп

    совершенно верно, только ваши методы почесать ухо ногой засунув руки в то место откуда они растут надо удалить и написать единственно правильное решение.
    как присвоить типу чар значение?

    ;
    вы же своим быдло кодингом заводите строки в сегменте констант, как минимум тратите в два раза больше памяти и кода на лишние преобразования.

  • Программист говорит:

    Здравствуйте! Я прочел вашу статью. Мне было очень грустно и одновременно смешно. Особенно убивает эта ваша фраза: «Так как переменную типа char часто используют как массив, то определяют количество возможных значений». 😆 😆 😆
    Я не смеюсь над вами. Создание сайта это действительно подвиг. Я лишь хочу поддержать вас советом и указать несколько ошибок.

    1. Значение переменной типа char присваивается так:

    char a = 'A';

    Вот здесь:

    char a = *"A";

    происходит разадресация указателя на массив и в результате возвращается значение первого элемента массива т.е. ‘A’

    2. Обнуление происходит так:

    char a = NULL;
    char b[10] = {};

    //А так очищается строка в теле программы

    b[0] = '';

    '' -- этот символ называется ноль-терминатор. Он ставится в конце строки. Вы сами того не зная заполнили этим символом массив s1 из вашей статьи. А ведь можно было присвоить этот символ только нулевому элементу массива.

    3. Смело пользуитесь терминологией.
    Знак = это операция присваивания.
    Знак * операция разадресации.
    Я имею в виду вот этот фрагмент статьи: "Настолько всё оказалось просто, перед знаком = нужно было поставить знак * и нужно было объявить номер элемента (ноль соответствует первому)"

    Поймите меня правильно, статья в нынешнем виде не может существовать. Не поленитесь, перепишите ее.
    На вас лежит большая ответственность! Я серьезно. Страницы вашего сайта попали в первую страницу выдачи Яндекса. Много людей уже начали повторять за вами ошибки.

    Удачи! Вы справитесь!

    Автор сайта отвечает:
    Я это давно знаю, просто трудно перечитывать 200 статей постоянно, чтобы что-то исправить. А некоторые грубые типы так пишут, что даже зная, что лучше исправить, исправлять совсем не охота.
    С вашим char b[10] = {}; Это не обнуление совсем. проверили бы хотя б.
    если говорить о нулевом символе '' ; Я хорошо знал, когда заполнял им строку и цель была в том, чтобы показать настоящее очищение, а не видимое на глаз, ибо в строку входит мусор, который иногда мешает. Вы бы с терминами сами поаккуратнее, "символ нуль-терминации" или просто "нулевой символ", не терминатор))) А символ-терминатор звучит просто круто.

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

    Я буду рад исправить и другие ошибки. поправить неточности, если они выскочат. Я ценю вашу помощь. спасибо.Я это давно знаю, просто трудно перечитывать 200 статей постоянно, чтобы что-то исправить. А некоторые грубые типы так пишут, что даже зная, что лучше исправить, исправлять совсем не охота.
    С вашим char b[10] = {}; Это не обнуление совсем. проверили бы хотя б.
    если говорить о нулевом символе '' ; Я хорошо знал, когда заполнял им строку и цель была в том, чтобы показать настоящее очищение, а не видимое на глаз, ибо в строку входит мусор, который иногда мешает. Вы бы с терминами сами поаккуратнее, "символ нуль-терминации" или просто "нулевой символ", не терминатор))) А символ-терминатор звучит просто круто.

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

    Я буду рад исправить и другие ошибки. поправить неточности, если они выскочат. Я ценю вашу помощь. спасибо.

    Здравствуйте еще раз!
    Хочу пояснить. Термином "ноль-терминатор" (terminator с англ. ограничитель) пользовался мой преподаватель в ВУЗе. Видимо это old school!
    Что касается обнуления строк.
    char b[10] = {}; Это действительно обнуление. Весь массив заполнен нулями. Не верите -- проверьте!
    Если рассматривать строку в её естественном, бытовом смысле, то "пустой" будет та строка в которой нет ни одного символа. Поэтому в 99.9% случаев достаточно поставить в начало нулевой символ. Обычно обработка строки идет до первого нулевого символа а какие символы идут за ним уже не важно. Я понимаю что вы хотели обнулить строку. Просто решил предложить проверенный временем классический вариант.

    Автор сайта отвечает:
    Когда "Обычно обработка строки идет до первого нулевого символа а какие символы идут за ним уже не важно" - да, строка обнуляется
    Если рассматривать "реальное обнуление всех ячеек строки (о котором писал я)" - нет, не обнуление и, даже, первый символ не нулевой. Я этим вариантом проверял. MinGW(CodeBlock) - весь массив отдает символ 'a'
    не думаю, что это повод для споров.

    И статью я уже модернизировал, скорее всего заметили. Оба варианта я показал.

    Я проверял Visual Studio 2010 и Dev-C++. Там все правильно работает. Видимо это отличия в реализации компиляторов.

    Автор сайта отвечает:
    Это интересный момент. Вообще "загадка MinGW"
    char
    char
    Как объяснить?
    =====================
    Хотя, оно позднее стало нормально обнуляться, я это признаю, но этот факт имел место быть.

  • Nik говорит:

    «…неполное очищение строки, а только частичное.» в конце статьи. Не, вроде, раздельно пишется в слове «неполное». и, кстати, «Максимуочень признателен…» — тут тоже, по-моему, что-то не так…)

  • Владимир говорит:

    Я не в чём не упрекаю автора. Просто как пользователь Linux таким же пользователям хочу добавить:

    Если вы пишете программу в Linux, то попытка присвоить переменной char символ кириллицы — вызовет ошибку компилятора. Так как символ кириллицы в данной операционной системе есть только в кодировке UTF8 и занимает 2 байта. Которые не смогут влезть в 1 байт отведённый компилятором под переменную типа char.

    В своё время, когда только начинал программировать, я долго не мог найти причину этой ошибки. Так что имейте в виду.

  • Сергей говорит:

    Здравствуйте. Поясните пожалуйста, почему строка

    присваивает в переменную аски-код единицы, а

    обнуляет символьную переменную, а не прописывает аски-код нуля?

    • admin говорит:

      Присваивает, просто объект cout проявляет инициативу и выводит значение переменной как тип char. Поэтому 0 превращается в признак конца строки: пустой символ.
      Если первый же символ является признаком конца строки, то строки как бы и нет.

      Если на экран выводить тип переменной в принудительной форме к int, то будет видно, что всё верно.

      ответ был исправлен намного позже, чем был задан вопрос

  • Аноним говорит:

    Здравствуйте!У меня возникла проблема при чтении текста.

    Как сделать так, чтобы человек ввел буквенное значение и оно записалось?

    • admin говорит:

      Для строки:

  • delphin говорит:

    char ch=‘y’;
    cout<<int(ch);

    Так правильно)

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     

Случайная книга в электронном формате

Яндекс.Метрика
НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Приходит программер в магазин. Подходит к витрине, хочет достать еды, но не может и говорит: - Rеаd оnlу, однако...

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок