2016-01-16 5 views
1

Почему при попытке вывести значение argv (которое в соответствии с Eclipse, для конкретного запуска программы ниже был 0x7fffffffd958) я получаю ffffd958 вместо 7fffffffd958?Hexadecimal усекается

int main (int argc, char *argv[]) { 
    printf("%x \n", argv); 
    return 0; 
} 
+3

Зачем вам лгать вашему компилятору? 'argv' является' char ** ', а не' unsigned int', поэтому используется для 'void *' и используется ''% p "' вместо ''% x''. – EOF

+0

Я знаю _print значение 'argv'_ - это то, что вы сказали, и все комментарии и ответы адресуются, но возможно ли, что вы действительно намеревались задать _print значение, содержащееся в' argv'_? – ryyker

+0

@ryyker, возможно, вас не часто интересует *, где * предоставленный массив 'char *' содержится в памяти. –

ответ

1

Короче говоря: вы вызываете неопределенное поведение из-за неправильного спецификатора формата. Вместо этого используйте:

printf("%p \n", (void *) argv); 

Причина, почему вы получите другое значение, что %x лечит argv, как 32-разрядное целое число без знака на вашей платформе. Вы могли бы , вероятно, использовать %lx (или, возможно, %llx), но это по-прежнему плохой и неправильный практику, так как argv имеет тип указателя.

+0

Я понимаю, что указатель хранит адрес памяти. Распечатав указатель argv так, как я делаю выше, правильно ли сказать, что я печатаю адрес в памяти начала массива, на который указывает argv? Что такое адрес, который хранится как (т. Е. Какой тип)? – Adam

+0

Это адрес, в котором находится начало массива указателей, * значение * 'argv', которое является базовым адресом массива указателей' char * '. –

+0

Адрес является шестнадцатеричным значением? 0x7fffffffd958 в этом случае? – Adam

2
#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    printf("%p\n", (void*)argv); 
    return 0; 
} 

Это будет заботиться о размере указательного типа, в отличие от размера unsigned int, которые не могут быть одинаковыми. Для формата %p требуется аргумент void*.

1

Использование %p для печати void * является правильным, но результат от %p определяется реализацией (поэтому он задокументирован), и он варьируется между платформами. В частности, некоторые платформы выводят ведущий 0x, некоторые нет. Я думаю, что все они используют шестнадцатеричный, но даже это не является обязательным (printf()):

p Аргумент должен быть указателем на void. Значение указателя равно , преобразованному в последовательность символов печати, в порядке реализации .

Альтернатива использует C99 средство от <inttypes.h>:

printf("0x%08" PRIXPTR "\n", (uintptr_t)argv); 

Технически uintptr_t является необязательным типом. На практике я не знаю системы, в которой она недоступна (но некоторые мейнфреймы или аналогичные компьютеры были бы вероятными кандидатами, если есть исключение). Это позволяет вам управлять форматом - мне нравится верхний регистр гексагона, за исключением ведущего падения 0xFEDCBA987654321, поскольку он равномерен, тогда как 0xfedcba имеет провалы для a, c и e. YMMV!