Разница проста: они приводят к появлению разных предупреждающих сообщений при компиляции:
1156942.c:7:31: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("memory address = %d\n", &a); // prints "memory add=-12"
^
1156942.c:8:31: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("memory address = %u\n", &a); // prints "memory add=65456"
^
Если вы передадите указатель как void*
и используете %p
в качестве спецификатора преобразования, то вы не получите сообщение об ошибке:
#include <stdio.h>
int main()
{
int a = 5;
// check the memory address
printf("memory address = %d\n", &a); /* wrong */
printf("memory address = %u\n", &a); /* wrong */
printf("memory address = %p\n", (void*)&a); /* right */
}