我对以下c程序的奇怪输出感到困惑。 我正在使用TurboC和DevC编译器
如果有人能帮助我,我会很高兴。
程序
#include<stdio.h>
#include<conio.h>
int main()
{
clrscr();
printf("%d","hb");
printf("%d","abcde"-"abcde");
//Output is -6 why ?
return 0;
}
输出 对于TurboC
printf("%d","hb");
//Output is 173 Why ?
// No matter what I write in place of "hb" the output is always 173
printf("%d","abcde"-"abcde");
//Output is -6 why ?
对于Dev C
printf("%d","hb");
//Output is 4210688 Why ?
// No matter what I write in place of "hb" the output is always 4210688
printf("%d","abcde"-"abcde");
//Output is 0 why ?
答案 0 :(得分:-2)
在这里,您传递的是字符串文字的内存地址(char*
):
printf("%d","hb");
但是,应该使用的说明符是%p
(代表指针):
printf("%p\n", "hb"); // The output is in hexadecimal
这将确保printf
在显示时使用相同的表示大小,并将其传递给printf
。当%d
与int
不同时,使用sizeof(int)
(sizeof(char*)
说明符)会导致未定义的行为,即使大小相等,也会使用{{1} }可能会导致打印负值(如果设置了最高有效位 - %d
的符号位)。
对于任何内存地址,在重新编译程序后,你不能指望它是相同的,在使用不同的工具链时甚至更少。
在将int
字面值更改为另一个字面值后输出相同时,表示它是在同一地址分配的。
这里,减去了两个指向字符串文字的指针:
"hb"
减去两个指针的结果是它们指向的地址之间该类型的元素数。 但请注意,仅当指针指向同一数组中的元素或指向数组末尾之后的第一个元素时才会定义行为。
同样,printf("%d","abcde"-"abcde");
可能不是正确使用的说明符。可以使用其大小至少等于指针类型的整数类型,可能是%d
(这应该针对特定平台进行检查)。可能仍会发生减法溢出,或者结果可能不适合强制转换类型,然后行为再次未定义。
long long int
另请注意,C标准库提供char *p1, *p2; // These should be initialized and NOT point to different arrays
printf("%lld\n", (long long int)(p1 - p2));
,它定义用于存储指针差异的stddef.h
类型。请参阅:C: Which character should be used for ptrdiff_t in printf?
注意:由于有两个不同的ptrdiff_t
数组,指针减法是未定义的,因此下面的信息仅基于假设,并且只是因为OP提到这是一个考试问题而提出。
在我们的例子中,当char
为1时,它完全代表字节的差异。 sizeof(char)
的不同之处在于,两个相同的文字-6
首先放在内存中,紧挨着第二个。文字包含字符串终止符,因此它的大小为6。
从这里可以推断出的另一件事是DevC ++使用的编译器“更聪明”(或者传递了其他优化选项),在内存中为"abcde"
文字创建单个副本,因此"abcde"
的差异。
字符串文字通常放在只读内存中,程序不应该尝试修改它,所以如果编译器(或某些情况下的链接器)可以“检测”重复,它可能会重用以前的字面意思。