2015-02-23 2 views
-1

Здравствуйте, я не в состоянии понять, как код ниже производить вывод как ffffffaa , пожалуйста, помогите мне понятьЯ не могу понять, как приведенный ниже код выводит вывод как ffffffaa, пожалуйста, помогите мне разобраться?

#include<stdio.h> 
int main() 
{ 
    int a=0xaaaaaaaa; 
    char *p=(char*)&a; 
    printf("%x\n",*p); 
} 
+1

У вас есть '#include '? 'int a = 0xaaaaaaaa;' присваивает значение, определяемое реализацией, 'a' (если только' int' не превышает 32 бит в вашей системе); использование 'unsigned int' будет более четким. Код в вашем вопросе не может создать вывод, который вы описываете ('% d' печатает десятичный, а не шестнадцатеричный); обновите свой вопрос, чтобы показать фактический код, который вы используете. –

ответ

5

функции VARIADIC как printf выполнить продвижение аргумента по умолчанию на своих хвостовых аргументов. A char рекламируется на int, а когда на платформе выставляется char, выполняется расширение знака.

Чтобы избежать знаковое расширение использования unsigned char типов или отливать *p к unsigned char в printf вызова программы.

1

Я не могу понять, как код выше может произвести ffffffaa, потому что он не может это сделать с помощью спецификатора "%d" ;-).

Вы, наверное, неправильно набранные вам пример кода, и это следует читать:

int main() { 
    int a=0xaaaaaaaa; 
    char *p=(char*)&a; 
    printf("%x\n",*p); 
} 

Для этого кода, чтобы произвести ffffffaa, символ должен быть 8-битным, и INT должны храниться в маленьком порядке Endian или имеет размер не более 32 бит.

&a - адрес первого байта a в памяти. Разъявление этого адреса в качестве char * загружает один байт и знак расширяет его как int перед передачей его printf, поскольку эта функция является переменной. Дополнительные аргументы в отношении вариационных функций с типами, меньшими, чем int, повышаются до int и передаются как таковые, а типы с плавающей запятой, меньшие, чем double, повышаются до double и передаются как таковые. printf получает int, но печатает шестнадцатеричное представление unsigned int для спецификатора формата %x. Это хорошая вещь int и unsigned int проходят тот же путь ;-)

Поскольку значение 0xaaaaaaaa имеет такое же представление в прямом порядке байтов и большой заказ Endian, ваш код не будет зависеть от байтов до тех пор, как int 32 бита или Меньше. Но на машине с 64-битным int в большом конце (например, некоторые поздние PowerPC) фактическая схема памяти a будет 00 00 00 00 aa aa aa aa. Затем ваш код будет генерировать вывод 0.

Вы можете узнать о с байтов этого образца кода:

#include <stdio.h>  
int main(void) { 
    int i, a = 0x12345678; 
    unsigned char *p = (unsigned char *)&a; 
    printf("Memory layout for %x is:", a); 
    for (i = 0; i < (int)sizeof(a); i++) 
     printf(" %02x", p[i]); 
    printf("\n"); 
} 

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

Смежные вопросы