Подтвердить что ты не робот

Как распечатать адрес памяти в C

Мой код:

#include <stdio.h>
#include <string.h>

void main()
    {
    char string[10];
    int A = -73;
    unsigned int B = 31337;

    strcpy(string, "sample");

    // printing with different formats
    printf("[A] Dec: %d, Hex: %x, Unsigned: %u\n", A,A,A);
    printf("[B] Dec: %d, Hex: %x, Unsigned: %u\n", B,B,B);
    printf("[field width on B] 3: '%3u', 10: '%10u', '%08u'\n", B,B,B);

    // Example of unary address operator (dereferencing) and a %x
    // format string 
    printf("variable A is at address: %08x\n", &A);

Я использую терминал в командной строке linux для компиляции, и когда я пытаюсь скомпилировать с помощью gcc, я получаю следующее сообщение об ошибке:

basicStringFormatting.c: In function ‘main’:
basicStringFormatting.c:18:2: warning: format ‘%x’ expects argument
of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("variable A is at address: %08x\n", &A);

Все, что я пытаюсь сделать, это напечатать адрес в памяти переменной A.

4b9b3361

Ответ 1

Используйте спецификатор формата %p:

printf("variable A is at address: %p\n", (void*)&A);

Стандарт требует, чтобы аргумент имел тип void* для спецификатора %p. Так как printf является вариационной функцией, нет никакого неявного преобразования в void * из T *, которое будет происходить неявно для любых невариантных функций в C. Следовательно, требуется бросок. Чтобы процитировать стандарт:

7.21.6 Форматированные функции ввода/вывода (проект C11)

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

В то время как вы используете %x, который ожидает unsigned int, тогда как &A имеет тип int *. Вы можете прочитать о спецификаторах формата для printf из руководства. Несоответствие спецификатора спецификаций в printf приводит к undefined поведению.

Ответ 2

Обходной путь для использования %x со спецификатором длины для печати int или unsigned int без компиляции с жалобой на приведение типа заключается в использовании malloc:

unsigned int* D = malloc(sizeof(unsigned int)); // Allocate D
unsigned int D_address = *((unsigned int*) &D); // D address for %08x without warning
*D = 75; // D value
printf("variable D is at address: %p / 0x%08x with value: %u\n", D, D_address, *D);

В качестве альтернативы вы можете скомпилировать с флагом gcc -w для подавления этих предупреждений о сотворении.