12

cでは、変数のアドレスといくつかの関数のアドレスを出力しようとしました。1つは負の値、もう1つは正の値です。私の質問は、Cがすべて負またはすべて正の値で表されないのはなぜですか?

これが私のコードです:

int foo() { 
     return 0;
}

int main() {

    int a;
    printf("%d\n",&a);

    printf("%d\n",foo);

    return 0;
}

結果は次のとおりです。

-1075908992 134513684
4

10 に答える 10

7

可能な限り最も標準に準拠するには、フォーマット文字列で「%p」をに渡しprintf()、引数をにキャストしますvoid*

printf("%p\n", (void*)&a);
printf("%p\n", (void*)foo);

ドラフト標準からの引用(n1401.pdf)

    7.20.6.1fprintf関数

8変換指定子とその意味は次のとおりです。

p引数は、voidへのポインタでなければなりません。ポインタの値
        で、一連の印刷文字に変換されます
        実装定義の方法。
于 2009-11-06T18:43:04.303 に答える
6

ポインターフォーマッターを渡す必要があります。

printf("%p\n",foo);
于 2009-11-06T18:32:27.730 に答える
3

ポインターは符号付き整数ではなく、符号なし整数によく似ています。ただし、符号付き整数であるかのように出力しています。int32 ビット システムでは、 、unsigned intfloat、およびポインターなど、 32 ビット長である可能性が高いものがいくつか あります。これらは一見しただけでは一般的にはわかりませんが、それぞれ意味が異なります。(実験として、さまざまな整数を渡して float のように出力したり、その逆を行ったりすることができます。これは一般的に悪い習慣ですが、異なるデータ型が異なることを意味することを示すことができます。)

可変数の引数をとる関数 (「可変個」関数) は、複雑な方法でそれを行います。特に、引数の型をチェックしません。好きな引数printf()や同様の関数を渡すことができますが、それらをフォーマット指定子に一致させるのはあなたの問題です。floatこれは、関数が適切な型を取得する方法がないことを意味します (のような関数にa を渡した場合と同様int foo(int))。

間違った型の引数を渡すと未定義の動作につながり、特に間違ったサイズの引数を渡すと問題が発生する可能性があります。ほとんどの 64 ビット システムでは、ポインタは 64 ビットで、ints は 32 です。

したがって、フォーマット文字列で正しいものを使用する必要があります。 printf("%p", &a);のアドレスをaポインタとして出力します。これはあなたが望むものです。標準では のようなものが必要ですprintf("%p", (void *)&a);が、実際には、遭遇する可能性のあるコンピューターでは不要です。

于 2009-11-06T19:07:10.077 に答える
0

printf は魔法の解釈ツールではありません。「%d」を指定すると、その変数にあるビットパターンが整数としてどのように見えるかが示されます。

一部のポインターが負で一部が正である理由については、上位ビットが設定されているものと設定されていないものがあることを意味します。オブジェクトにどのアドレスが与えられるかは、実際にはオペレーティングシステムの仕事にすぎません (通常はハードウェアの助けを借りて)。プログラミング言語には、実際の発言権はありません。

私があなたなら、そのように住所を印刷することはありません。それらを確認する必要がある場合は、"%d" の代わりに "%x" を使用してください。これにより、それらが 16 進数で出力されるため、オンになっているビットとそうでないビットを簡単に把握できます。一般に、アドレスに関して気にすることは、それらが 0 であるかどうか、およびそれらが他のアドレスの値と一致するかどうかだけです。

于 2009-11-06T18:56:31.910 に答える