2014-09-16 5 views
0
#include<stdio.h> 

int main()        
{       
    int a = 0xabcdef; 

    char *b = &a; 
    printf("%x",*b); 

    return 0; 
}  

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

+4

Это неопределенное поведение, но вы просто берете младший байт (0xef) - потому что, по-видимому, ваша система немного суетна, а затем обрабатывает его как int и sign-extend. –

+3

@ user3411451: Почему вы игнорируете диагностические сообщения от вашего компилятора? Инициализация 'b' с' & a' является незаконной. Если вы действительно хотите это сделать, вы должны использовать явное приведение. – AnT

+1

Всегда запускайте свой компилятор в строжайшем режиме проверки ошибок. * По крайней мере * это должно включать '-Wall -Werror' (если используется GCC), и есть * lots * дополнительных доступных вариантов предупреждения. – DevSolar

ответ

1

Указатель *b является указателем типа char и указывает на переменную типа int. В этом причина неправильного вывода. Объявите переменную указателя *b как int типа.

int a = 0xabcdef;  

int *b = &a; 
printf("%x",*b); 
1

Во-первых, переменная b объявлена ​​с типом char *. Вы пытаетесь инициализировать его значением &a типа int *. Это незаконно. Код недействителен C. Поведение не определено.

Во-вторых, если ваш компилятор сумел пропустить эту инициализацию, то, вероятно, он выполнил неявное преобразование значения int * в char *. Это делает указатель b указывать только на один байт переменной a. Значение этого единственного байта - это то, что вы видите через *b. Какой из байтов (в терминах исходного значения a) определяется реализацией. Например. вы обычно получаете младший байт (0xEF) или старший байт (0xAB).

В-третьих, это определение реализации, независимо от того, подписан или нет знак char. Это означает, что значение *b может быть подписано или без знака в зависимости от вашей реализации. Когда вы передаете char значение *b на вариационную функцию printf, то значение char значение автоматически преобразуется в int. Результат этого преобразования, как правило, зависит от подписи типа char. Если ваш b указывает на байт, char подписан и int имеет ширину в 32 бит и использует 2'-дополнение, то результат в шестнадцатеричном выражении будет выглядеть как 0xFFFFFFEF (что отрицательное значение).

В-четвертых, спецификатор формата %x требует аргумента unsigned int, но вместо этого вы передаете аргумент int с потенциально отрицательным значением. Поведение не определено.

Другими словами, ваша программа - просто большая куча неопределенного и определенного по реализации поведения. Нет смысла пытаться объяснить, почему вы получили этот конкретный результат.

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