Olá.
Sim, tem diferenças. Um ponteiro armazena somente um endereço de memória, um int, double ou float armazena o valor.
O printf com %p é voltado para imprimir o endereço de memória em hexadecimal, já o %d ou %i o valor de um inteiro.
O tamanho que um ponteiro usa de memória para guardar um endereço é de 8 bytes, já um int
usa metade disso (em GCC, 64 bits). Essa diferença pode te causar problemas a depender do tamanho dos valores das variáveis, e seu programa pode não se comportar como esperado. Um dos sinais é que o compilador emite avisos de que você está usando o printf para um tipo que é diferente do esperado. Avisos não impedem seu código de compilar, mas sinalizam que algo pode causar más surpresas em tempo de execução.
Por exemplo:
int main() {
int x = 5;
int* ptr_to_int = &x;
printf("Number: %d\n", ptr_to_int);
return 0;
}
Nesse exemplo, o printf
tenta converter um endereço de memória, que seria o ponteiro para um valor inteiro. O resultado é o seguinte:
Number: -1360474196
Não existe endereço de memória negativo. O que houve foi que o endereço de memória era um valor bem mais alto que o valor máximo que um int consegue armazenar, e aí deu esse comportamento estranho.
O compilador poderia muito bem dizer "eu avisei", por que ele realmente avisa:
ptr_test.c: In function ‘main’:
ptr_test.c:6:26: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]