在我的 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
它接受带有大量警告的程序。而且没有一个词说“存储类”。所以我想知道你使用的是什么版本的 GCC?
前两个警告可以通过#include <stdio.h> 修复,并将printf 函数调用中的%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),它会返回一个指针,或者返回js的值。这种情况下的结果是0x14(记住我们需要将%d替换为%p,所以输出是十六进制的)。
编辑
查看您的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,因此 printf 的 %p 将恢复为 %d。输出与原代码相同:20。