Ubuntu 13.04 で GCC 4.7.3 を使用している私のマシンでは、出力は次のようになります。
$gcc test.c
test.c: In function ‘main’:
test.c:7:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
test.c:7:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
test.c: In function ‘check’:
test.c:13:12: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:14:12: warning: initialization makes pointer from integer without a cast [enabled by default]
$./a.out
20
多くの警告を伴うプログラムを受け入れます。そして、「ストレージ クラス」という言葉は 1 つもありません。使用しているGCCのバージョンは何ですか?
最初の 2 つの警告は、への printf 関数呼び出しで修正#include <stdio.h>
および変更できます。ここではそれらを無視して、残りの 2 つに注目しましょう。やりたいことに応じて、それらを排除するためのさまざまなオプションを使用できます。%d
%p
i
またはのアドレスをスタックベースの変数として返したい場合j
(呼び出し元に戻った後は無効になるため、これは珍しいことです)、次のことができます。
int *check( int i, int j)
{
int *p = &i;
int *q = &j;
...
レジスタ変数のアドレスを取得できないため、それらを削除する必要があります。この場合、関数を使用すると、プログラムは私のマシンのmain
ように出力されます。0x7fffc83021f8
これは変数へのポインター値j
ですが、出力する時点では有効ではありませんが、逆参照を試みない限り、すべて問題ありません。
これがあなたが望むものではない場合、おそらく整数を強制するi
かj
、ポインターを表現したい場合は、次のことを行う必要があります
int *check(register int i,register int j)
{
int *p=(int *)i;
int *q=(int *)j;
if(i >= 45)
return (p);
else
return (q);
}
この場合、register キーワードの使用は問題ありませんが、効果は非常に限られていることに注意してください。また、一部のマシン (特に 64 ビット GCC) でコードをコンパイルするときにも警告が表示されます。
奇妙ですが、このコードにはある程度の意味があります。通常、ゼロに近すぎる整数は有効なポインターではありません。
したがって、このコードが行うことは次のとおりです。i
の値が有効なポインター (値が 45 より大きい) である場合は、 の値をポインターとして返すか、またはj
s の値を返します。この場合の結果は次のようになり0x14
ます ( を に置き換える必要が%d
ある%p
ため、出力は 16 進数になります)。
編集
あなたのmain
機能を見た後、私はここで何が求められていると信じています
int check(register int i,register int j)
{
int p=i;
int q=j;
if(i >= 45)
return (p);
else
return (q);
}
とにかく、このコードは次のように簡略化できます
int check(register int i,register int j)
{
if(i >= 45)
return i;
else
return j;
}
あるいは
int check(register int i,register int j)
{
return i>=45 ? i : j;
}
これらの場合、main
関数は
int main()
{
int c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
のデータ型が になってc
いるint
ため、%p
forprintf
が に復元されることに注意してください%d
。出力は元のコードと同じです: 20
.