При использовании и int для чтения символа, почему значение 4096 + ascii - PullRequest
0 голосов
/ 11 февраля 2011

Я использовал gcc и тестировал различные способы обработки символов, используя целые числа или символы в качестве типа данных.

int main() {
    int i;      
    printf("Enter a char: ");
    scanf(" %c", &i);
    printf("integer value= %d     char value=%c", i, i);
    return 0;
}

Выход:

Enter a char: f    
integer value= 4198     char value=f

Мне любопытно, какое целое значение хранится. Похоже, что значение равно 4096 + значение ASCII 'F'.

Мой вопрос: почему 4096 добавляется к значению ascii персонажа? Что представляет собой это значение?

Ответы [ 2 ]

4 голосов
/ 11 февраля 2011

Введите следующую программу, и вы поймете, почему:

#include <stdio.h>

int main (void) {
    int val = 4096;
    printf ("Enter your character: ");
    scanf ("%c",&val);
    printf ("integer val = %d, character val = %c\n", val, val);
    return 0;
}

Компиляция этого с gcc -Wall (все предупреждения), дает:

qq.c: In function 'main':
qq.c:6: warning: format '%c' expects type 'char *',
        but argument 2 has type 'int *'

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

Enter your character: f
integer val = 4198, character val = f

Причина 1012 * для этого способа scanf работает в сочетании сспособ размещения переменных в памяти.

Чтобы scanf просто получил символ и поместил его в память.Поскольку вы дали ему адрес integer , и это целое число имеет младший порядок, оно будет перезаписывать только младший байт (LSB) этого целого числа.Подумайте о том, чтобы рассматривать эту память как перекрывающуюся область, и вы поймете, почему:

    +--- The address passed to scanf.
    |
    V
+------+
| char |                       <-- Treated as char.
+------+------+------+------+
| lsb  |      |      | msb  |  <-- Treated as integer (assumes 32-bit).
+------+------+------+------+

Поскольку scanf не касается этих самых правых байтов целого числа, они остаются с тем, что они держали до вызова.В моем коде я явно устанавливаю значение 4096, но если ваше объявление неинициализировано int val;, содержимое будет неопределенным.Фактически, когда я удаляю инициализацию, я получаю 1629542246 (0x6120D766, и вы все еще можете видеть LSB, установленный в 0x66 или f).

Это просто означает, что мое целое число выглядело такдо того, как вызов scanf:

+------+
|  ??  |
+------+------+------+------+
|  ??  |  d7  |  20  |  61  |
+------+------+------+------+

и вызов scanf изменили только бит ??.

0 голосов
/ 11 февраля 2011

Вы инициализируете int перед чтением в char? Может быть просто неинициализированным значением. Вы можете показать код? Какие функции используют чтение символа в int?

4096 - это 0x00001000 в шестнадцатеричном формате. Может быть флаг или что-то до или после символа, или количество прочитанных символов, в зависимости от того, что вы используете для чтения символа.

...