2014-11-25 65 views
1

我编译下面的C代码:打印负INT只要产生错误的结果

#include <stdio.h> 

int main() 
{ 
    int nEndIndex = -1; 
    printf("nEndIndex : %ld\n", nEndIndex); 
    return 0; 
} 

我用GCC 4.2.4编译它,如下所示:

[[email protected] ~/junk]$ gcc -o test test.c 
[[email protected] ~/junk]$ ./test 
nEndIndex : 4294967295 
[[email protected] ~/junk]$ gcc --version 
gcc (GCC) 4.2.4 
Copyright (C) 2007 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

,因为我想long大于int使用%ld应该不成问题。因为他们都是signed为什么我得到这个输出?

+0

它为我打印-1。 gcc版本4.6.3 – 2014-11-25 04:46:16

+0

@RaghuSrikanthReddy:只有运气。行为是未定义的。 – 2014-11-25 04:51:04

回答

5

参数的类型(在升级之后,在这种情况下不适用)必须匹配格式字符串的预期类型;否则行为是不确定的。

int传递给期望long int的函数通常是允许的,并且会导致隐式转换。但对于像printf这样的可变参数函数,编译器不知道将参数转换为什么类型。

行为是不确定的,这意味着可以发生任何事情(包括,如果你是不幸,代码似乎工作“正确”)。在实践中,我们假设int是32位,long是64位(这些大小因系统而异)。 printf可能会从堆栈中获取64位数据,从您的参数中获取32位数据和另外32位垃圾;它会打印该数据假设它是一个long int对象(因为这是你通过格式字符串告诉的)。

对于int参数使用%d,对于long int参数使用%ld

+0

我知道我应该使用'%d'这只是我期望'long int'能够完美地与'int'一起工作 – 2014-11-25 04:51:23

+0

@KartikAnand:你为什么期待? – 2014-11-25 04:52:08

+0

那么因为'long int'大于'int',所以不应该有任何问题。正如我们预计'unsigned long'与'void *'一起工作,因为它具有相同的宽度。 – 2014-11-25 04:53:48

0

该变量未被声明为long int。声明应该是long int nEndIndex = -1;

+0

*或*'printf'格式应该是'%d'而不是'%ld'。 – 2014-11-25 05:13:48