Arhn - архитектура программирования

назначение более одного символа в char

Почему эта программа выдает результат 'y'

#include <stdio.h>

int main(void) {
    char ch='abcdefghijklmnopqrstuvwxy';
    printf("%c",ch);
    return 0;
}

Код в ideone

10.07.2015


Ответы:


1

Это многосимвольный литерал.

Обычный символьный литерал, содержащий более одного c-char, является многосимвольным литералом. Многосимвольный литерал имеет тип int и значение, определяемое реализацией.

Также из 6.4.4.4/10 в спецификациях C11

Целочисленная символьная константа имеет тип int. Значение целочисленной символьной константы, содержащей один символ, который отображается на однобайтовый символ выполнения, является числовым значением представления отображаемого символа, интерпретируемого как целое число. Значение целочисленной символьной константы, содержащей более одного символа (например, 'ab') или содержащую символ или управляющую последовательность, которая не соответствует однобайтовому символу выполнения, определяется реализацией. Если целочисленная символьная константа содержит одиночный символ или escape-последовательность, ее значение равно тому, которое получается, когда объект с типом char, значение которого является значением одиночного символа или escape-последовательности, преобразуется в тип int.

Таким образом, строка char ch = 'abcdefghijklmnopqrstuvwxy' в вашей системе (предполагая 4 байта int), возможно, компилируется в:

char ch = 0x76777879;  // SOME int value (may be different, but documented in the compiler documents)

ch будет назначено 'abcdef...y' что может быть эквивалентно (int)0x616263646566...79 в кодировке ascii и переполняет целое число. По этой причине gcc выдает следующее предупреждение:

multicharlit.c: В функции 'main':
multicharlit.c:4:13: предупреждение: символьная константа слишком длинная для своего типа [включено по умолчанию]
multicharlit.c:4:5: предупреждение : переполнение при неявном преобразовании констант [-Woverflow]

В вашей системе младшие 8 бит используются для назначения ch. Поскольку ваш символьный литерал является постоянным, это, скорее всего, происходит во время компиляции: (Например, следующее происходит, когда я компилирую с gcc)

$ cat multicharlit.c
#include <stdio.h>

int main(void) {
    char ch='abcdefghijklmnopqrstuvwxy';
    printf("%c",ch);
    return 0;
}

$ gcc -O2 -fdump-tree-optimized multicharlit.c 
$ cat multicharlit.c.143t.optimized 

;; Function main (main) (executed once)

main ()
{
<bb 2>:
  __builtin_putchar (121);
  return 0;

}

Также украл немного добра из комментария unwind

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

Тип 'a', например, int в C. (Не путать с 'a' в C++, который является символом. С другой стороны, тип 'ab' — это int в оба C и C++.)

Теперь, когда вы назначаете этот тип int типу char, а значение больше, чем может быть представлено char, тогда необходимо сделать некоторое сжатие, чтобы результат соответствовал менее широкому типу char, а фактический результат определяется реализацией.

10.07.2015
  • @LoveToCode: компилятор должен задокументировать поведение, определяемое реализацией, и, предположительно, используемый вами компилятор помещает последний символ многосимвольной константы в значение символа. Это мог быть первый, или четвертый, или любой другой символ, выбранный реализацией — она просто должна задокументировать то, что она решила сделать (и тогда она тоже должна это сделать). 25.07.2015

  • 2

    Если вы намеревались вывести abcdefghijklmnopqrstuvwxy, вы должны были сохранить его в строковой переменной, а не в символьной (char ch[50] = char abcdefghijklmnopqrstuvwxy;).

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

    28.08.2015
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..


    © 2024 arhn.ru, Arhn - архитектура программирования