看到了这个网址http://www.gowrikumar.com/c/,作者收集了一系列网上和自己所遇到的C语言有趣的东西,我感觉挺像<Java解惑>的风格,我下面就尝试解决一下作者提出的问题.
第一题
The expected output of the following C program is to print the elements in the array. But when actually run, it doesn't do so.
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
Find out what's going wrong.
这道题作者给出了提示,因为sizeof操作符返回的是size_t类型,一般情况下size_t是无符号类型,所以在for循环中当-1与(TOTAL_ELEMENTS-2)比较时,-1首先被转换成无符号数来进行比较,此时-1被解释为一个很大的整数,大于(TOTAL_ELEMENTS-2)的值,所以代码什么也不输出,与程序作者本意相违背.
第二题:
I thought the following program was a perfect C program. But on compiling, I found a silly mistake. Can you find it out (without compiling the program :-) ?
#include<stdio.h>
void OS_Solaris_print()
{
printf("Solaris - Sun Microsystems\n");
}
void OS_Windows_print()
{
printf("Windows - Microsoft\n");
}
void OS_HP-UX_print()
{
printf("HP-UX - Hewlett Packard\n");
}
int main()
{
int num;
printf("Enter the number (1-3):\n");
scanf("%d",&num);
switch(num)
{
case 1:
OS_Solaris_print();
break;
case 2:
OS_Windows_print();
break;
case 3:
OS_HP-UX_print();
break;
default:
printf("Hmm! only 1-3 :-)\n");
break;
}
return 0;
}
这道题比较简单,就是函数OS_HP-UX_print()中间不能有符号-,作者也给出了提示.
第三道题:
What's the expected output for the following program and why?
enum {false,true};
int main()
{
int i=1;
do
{
printf("%d\n",i);
i++;
if(i < 15)
continue;
}while(false);
return 0;
}
作者也给出了提示,在K&R的书中提到,在while与do while语句中,continue语句的执行意味着立即执行测试部分.所以上述程序只输出1,同时要注意程序没有导入stdio.h头文件,在一些编译器上会出错.
第四道题:
The following program doesn't "seem" to print "hello-out". (Try executing it)
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
What could be the reason?
这道题我不明白,应该是与多线程之类的有关系(以后再弄)
第五道题:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n",h(f(1,2)));
printf("%s\n",g(f(1,2)));
return 0;
}
Just by looking at the program one "might" expect the output to be, the same for both the printf statements. But on running the program you get it as:
bash$ ./a.out
12
f(1,2)
bash$
Why is it so?
这道题我也不明白,以后再做
第六道题:
#include<stdio.h>
int main()
{
int a=10;
switch(a)
{
case '1':
printf("ONE\n");
break;
case '2':
printf("TWO\n");
break;
defa1ut:
printf("NONE\n");
}
return 0;
}
If you expect the output of the above program to be NONE, I would request you to check it out!!
这道题需要细心观察,default在程序中被写成了defalut,而这在某些编译器是可以编译运行的(我在gcc,vc测过,是可以运行的),所以程序什么都不会输出.
第七道题:
The following C program segfaults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?
注意这个程序没有引入malloc函数原型所在的头文件,在IA-32平台下,因为没有指定头文件,编译器默认返回了一个32位的指针类型,在IA-64的情况下,因为没有指定头文件编译器还是返回的32位的,这样在转换的过程中将64位的截断成了32位,所以就出现段错误了.
第八道题:
Here is a small piece of program(again just 14 lines of program) which counts the number of bits set in a number.
Input Output
0 0(0000000)
5 2(0000101)
7 3(0000111)
int CountBits (unsigned int x )
{
static unsigned int mask[] = { 0x55555555,
0x33333333,
0x0F0F0F0F,
0x00FF00FF,
0x0000FFFF
} ;
int i ;
int shift ; /* Number of positions to shift to right*/
for ( i =0, shift =1; i < 5; i ++, shift *= 2)
x = (x & mask[i ])+ ( ( x >> shift) & mask[i]);
return x;
}
Find out the logic used in the above program.
位运算技巧的运用,以后再弄
第九道题:
What do you think would be the output of the following program and why? (If you are about to say "f is 1.0", I would say check it out again)
#include <stdio.h>
int main()
{
float f=0.0f;
int i;
for(i=0;i<10;i++)
f = f + 0.1f;
if(f == 1.0f)
printf("f is 1.0 \n");
else
printf("f is NOT 1.0\n");
return 0;
}
浮点数加减法有很多让人意想不到的东西,特别是大数与小数相加时,所以出书f is NOT 1.0就是不足为奇了.
第十道题:
I thought the following C program is perfectly valid (after reading about the comma operator in C). But there is a mistake in the following program, can you identify it?
#include <stdio.h>
int main()
{
int a = 1,2;
printf("a : %d\n",a);
return 0;
}
这里逗号的本意是将两个句子和在一块,少写分号.但是int a = 1做单个句子缺少分号;所以出现编译错误,要想避免编译错误有两种方法,第一种:将1,2用括号括起来,即a = (1,2);这时候a被初始化为2,或者int a; a = 1,2;此时a = 1.
第十一道题:
What would be the output of the following C program? (Is it a valid C program?)
#include <stdio.h>
int main()
{
int i=43;
printf("%d\n",printf("%d",printf("%d",i)));
return 0;
}
printf函数的返回值是被打印的字符数,所以程序输出4321,另外这道题是ppurl.com注册时的一个题,很有点意思.
第十二道题:
void duff(register char *to, register char *from, register int count)
{
register