Qual é a diferença de usar\% p,\% u e\% x para imprimir o endereço da variável em C?


Melhor resposta

Se você precisar imprimir o endereço de algo , ou o conteúdo de uma variável de ponteiro, a única maneira verdadeiramente portátil de fazer isso é usar o especificador de formato\% p. O padrão C afirma que os caracteres impressos são definidos pela implementação, mas na prática, a maioria das implementações da biblioteca C geram uma sequência de dígitos hexadecimais representando o endereço.

Os especificadores de formato\% u e\% x esperam um inteiro sem sinal e imprime o valor em decimal e hexadecimal, respectivamente. Eles não esperam um endereço .

Se você usar\% u ou\% x (ou qualquer coisa diferente de\% p) para tentar imprimir um endereço, ele pode parecer funcionar em alguns ambientes, mas na verdade será comportamento indefinido e não portátil . Você não pode assumir que o tamanho de um ponteiro é o mesmo que o tamanho de um inteiro sem sinal (ou qualquer outro tipo de dados inteiro). Por exemplo, em muitos ambientes de 64 bits, um inteiro não assinado tem 32 bits. Se o número de bits em um ponteiro não corresponder ao número de bits em um inteiro sem sinal em seu ambiente, e você tentar usar\% u ou\% x para imprimir um endereço, obterá uma saída incorreta e a saída de itens na mesma chamada para printf também podem estar incorretos.

Portanto, se você for imprimir um endereço, sempre use o especificador de formato\% p, para código portátil que evita comportamento indefinido. Nunca assuma que o tamanho de um ponteiro é igual ao tamanho de qualquer outro tipo de dados C.

Resposta

Apenas o \%p a conversão entende corretamente um ponteiro. A conversão \%p imprime um ponteiro de uma forma específica de implementação.

O \%u e \%x As conversões são para os tipos unsigned int ou int, que podem ou não ter o mesmo tamanho de um tipo de ponteiro. A conversão \%u imprime um inteiro decimal sem sinal, enquanto \%x imprime um inteiro hexadecimal sem sinal em minúsculas.

Para imprimir um ponteiro com \%u ou \%x, você precisará lançar o ponteiro para um int ou unsigned int. Esse elenco pode perder informações se sizeof(void *) > sizeof(int).

Veja também: printf, fprintf, sprintf, snprintf, printf\_s , fprintf\_s

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *