嗯,在网上看到的C语言的一些有趣的谜题,摘录过来,以后也能看看。

1、下面的程序会有什么样的输出呢?

#include
int main()
{
        int i=43;
        printf("%d\n",printf("%d",printf("%d",i)));
        return 0;
}
参考答案:程序会输出4321,你知道为什么吗?要知道为什么,你需要知道printf的返回值是什么。printf返回值是输出的字符个数。

2、下面的程序会输出什么?

#include
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", (int)a);
printf("%d\n", *(int *)&a);
return 0;
}
参考答案:该项程序输出如下所示, 0 12 1095237632 原因是:浮点数是4个字节,12.5f 转成二进制是:01000001010010000000000000000000,十六进制是:0x41480000,十进制是:1095237632。所以,第二和第三个输出相信大家也知道是为什么了。而对于第一个,为什么会输出0,我们需要了解一下float和double的内存布局,如下:

float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)
double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)
然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。别忘了在x86芯片下使用是的反字节序,高位字节和低位字位要反过来。所以:

float版:0x41480000 (在内存中是:00 00 48 41)
double版:0x4029000000000000 (在内存中是:00 00 00 00 00 00 29 40)
而我们的%d要求是一个4字节的int,对于double的内存布局,我们可以看到前四个字节是00,所以输出自然是0了。 这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。

3、下面,我们再来看一个交叉编译的事情,下面的两个文件可以编译通过吗?如果可以通过,结果是什么?

file1.c

int arr[80];
file2.c

extern int *arr;
int main()
{
arr[1] = 100;
printf("%d\n", arr[1]);
return 0;
}
参考答案:该程序可以编译通过,但运行时会出错。为什么呢?原因是,在另一个文件中用 extern int *arr来外部声明一个数组并不能得到实际的期望值,因为他们的类型并不匹配。所以导致指针实际并没有指向那个数组。注意:一个指向数组的指针,并不等于一个数组。修改:extern int arr[]。(参考:ISO C语言 6.5.4.2 节)

4、请问下面的程序输出什么?

#include
int main()
{
int i;
i = 10;
printf("i : %d\n",i);
printf("sizeof(i++) is: %d\n",sizeof(i++));
printf("i : %d\n",i);
return 0;
}
参考答案:如果你觉得输出分别是,10,4,11,那么你就错了,错在了第三个,第一个是10没有什么问题,第二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。

5、下面的C程序是合法的吗?如果是,那么输出是什么?

#include
int main()
{
int a=3, b = 5;

printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]);

printf(&a["WHAT%c%c%c %c%c %c !\n"], 1["this"],
2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]);

return 0;
}
参考答案:本例是合法的,输出如下:

Hello! how is this? super That is C !
本例主要展示了一种另类的用法。下面的两种用法是相同的:

"hello"[2] 2["hello"]
如果你知道:a[i] 其实就是 *(a+i)也就是 *(i+a),所以如果写成 i[a] 应该也不难理解了。

6、请问下面的程序输出什么?(假设:输入 Hello, World)

#include
int main()
{
char dummy[80];
printf("Enter a string:\n");
scanf("%[^r]",dummy);
printf("%s\n",dummy);
return 0;
}

参考答案:本例的输出是“Hello, Wo”,scanf中的"%[^r]"是从中作梗的东西。意思是遇到字符r就结束了。