Обе строки printf должны печатать адрес переменной, верно? но они оба дают разное значение... Почему так, оба должны давать одинаковое значение, потому что место в памяти, выделенное для переменной a, фиксировано.

#include <stdio.h> 

void main()
{
    int a = 5;
    int *ptra = &a;
    printf("%d", &a);
    printf("%p", ptra);
}
0
Vishal Mourya 4 Фев 2022 в 09:15
6
Используйте %p для обоих printfs, и вы должны получить правильный результат.
 – 
tkausl
4 Фев 2022 в 09:17
3
Печать указателя с использованием %d является поведением undefined. Другими словами: он может напечатать любое значение. Всегда используйте %p для указателей
 – 
4386427
4 Фев 2022 в 09:26
1
И всегда приводите значение указателя к void*. %p специально требует аргумента void*, а не указателя любого типа.
 – 
Keith Thompson
4 Фев 2022 в 09:37

2 ответа

Они одинаковые. Вы печатаете один в десятичной форме, другой в шестнадцатеричной форме.

#include<stdio.h> 
int main(int argc, char **argv)
{
    int a=5;
    int *ptra=&a;
    printf("%p\r\n",&a);
    printf("%p\r\n",ptra);
    return 0;
}

Отпечатки

0x7ffc8e4cb974
0x7ffc8e4cb974

Для меня

1
Mert Can Ergün 4 Фев 2022 в 09:36
2
\r не нужен. Если вы работаете в системе, использующей окончания строк CR-LF, простой \n будет переведен по мере необходимости. Если вы работаете в системе, использующей только LF, \r неверен.
 – 
Keith Thompson
4 Фев 2022 в 09:29
Печать указателей с %d является UB
 – 
phuclv
4 Фев 2022 в 09:33
Обновлен код для удаления %d
 – 
Mert Can Ergün
4 Фев 2022 в 09:37

Как уже упоминалось в ответе Кейта Томпсона (https://stackoverflow.com/a/70982344/4386427), причина заключается в том, что вы печатаете целочисленное значение, используя %d, но аргумент не является целым числом — это значение указателя. Предоставление аргумента с типом, который не соответствует спецификатору формата (т. е. предоставление значения указателя для %d), приводит к неопределенному поведению, что означает, что он может напечатать любое значение, текст или даже ничего.

Все это уже хорошо описано Китом Томпсоном (https://stackoverflow.com/a/70982344/4386427)

Я просто хочу добавить, что если вы действительно хотите напечатать десятичное целочисленное представление значения указателя, вы можете использовать типы intptr_t или uintptr_t. Нравится:

#include <stdio.h> 
#include <inttypes.h> 
int main(void)
{
    int a = 5;
    int *ptra = &a;
    printf("%p\n", (void*)&a);
    printf("%p\n", (void*)ptra);
    
    intptr_t dptr = (intptr_t)(void*)ptra;
    uintptr_t uptr = (uintptr_t)(void*)ptra;

    printf("A signed integer representation of the same pointer in decimal        : %" PRIdPTR "\n", dptr);
    printf("An unsigned integer representation of the same pointer in decimal     : %" PRIuPTR "\n", uptr);
    printf("An unsigned integer representation of the same pointer in hexadecimal : %" PRIxPTR "\n", uptr);

}

Возможный выход:

0x7ffcaceba19c
0x7ffcaceba19c
A signed integer representation of the same pointer in decimal        : 140723209609628
An unsigned integer representation of the same pointer in decimal     : 140723209609628
An unsigned integer representation of the same pointer in hexadecimal : 7ffcaceba19c
0
4386427 4 Фев 2022 в 10:12