在我在 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?
前两个警告可以通过printf 函数调用来修复#include <stdio.h>
和更改。让我们暂时忽略这些并关注其余两个。取决于你想做什么,你可以有不同的选择来消除它们。%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
,所以输出是十六进制的)。
编辑
在查看您的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
.