web-dev-qa-db-ja.com

Cでメモリアドレスをprintfする方法

私のコードは:

#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 mintのターミナルを使用してコンパイルしていますが、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のメモリ内のアドレスを出力することです.

18
varlotbarnacle

書式指定子%pを使用します。

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

標準では、void*指定子の場合、引数は%p型である必要があります。 printfは可変長関数であるため、Cの非可変長関数に対して暗黙的に発生するvoid *からT *への暗黙的な変換はありません。したがって、キャストが必要です。標準を引用するには:

7.21.6書式付き入出力関数(C11ドラフト)

p引数はvoidへのポインターでなければなりません。ポインターの値は、実装定義の方法で、印刷文字のシーケンスに変換されます。

一方、%xunsigned intであるのに対し、&Aint *である必要があります。 マニュアルのprintf のフォーマット指定子について読むことができます。 printfのフォーマット指定子の不一致は、 undefined behaviour につながります。

41
P.P.