读书人

C puzzle(一)

发布时间: 2013-04-26 16:27:53 作者: rapoo

C puzzle(1)
#include<stdio.h> #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { for(int d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; }

分析:sizeof操作符以字节形式给出了其操作数的存储大小,其中操作数可以是一个表达式或括在括号内的类型名,即sizeof(type)、sizeof(var_name)或sizeof var_name,操作数的存储大小由操作数的类型决定,返回的是unsigned类型,这样TOTAL_ELEMENTS-2就为5。d是int类型,在与无符号数TOTAL_ELEMENTS-2作比较的时候会进行无符号类型保护,转换为unsigned类型,所以for的条件判断为假,跳出循环。根据IEEE的内存结构,有符号正数的最高位为标志位,用来标识正负数,正数的最高位为0,负数的最高位为1,因此二进制比较时,负数永远大于正数。

(#define的用法见http://blog.csdn.net/benny5609/article/details/2314541)

修改如下,则可运行。

          int m=TOTAL_ELEMENTS-2;          for(int d=-1;d <= m;d++)             printf("%d\n",array[d+1]);

?还是不知道啊!!!纠结T0T。。。

?========================================================================

2.不能运行:

?

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;}
?原因:变量名由字母、数字和_组成,且第一个字符必须为字母!!

===========================================================================

3.continue用于使用for、while和do-while语句开始下一次循环的执行:在while和do-while语句中,continue意味着立即执行测试部分;在for循环中,则意味着控制转移到递增循环变量部分。continue只用于循环语句,不用于switch语句。

break语句用于从for、while和do-while等循环中提前退出。break能使程序从switch语句或最内层循环中立即跳出。

===========================================================================

4.一下程序输出“hello-out”

?

  #include <stdio.h>  #include <unistd.h>//VS中无此文件,调用<windows.h>的Sleep()方法  int main()  {          while(1)          {                  fprintf(stdout,"hello-out");                  fprintf(stderr,"hello-err");                  sleep(100);          }          return 0;  }
?程序连续输出hello-outhello-err,自动转行。

?

stdout -- 标准输出设备 (printf("..")) ;stderr -- 标准错误输出设备。两者默认向屏幕输出。

但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。用法:

fprintf(stderr, "Can't open it!\n");

fprintf(stdout, "Can't open it!\n");

========================================================================

5.以下程序运行结果为12 ? f(1,2)?

?

  #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;  }

???? ? ?这里要说一下宏的展开次序,如果宏有参数,如f(a,b)中的a和b,我们称之为形参,而宏实际的参数我们称之为实参,如f(1,2)中的1和2。宏的展开是个很复杂的过程,但可以用以下三步来简单描述:

首先用实参替换形参,将实参代入宏文本中;

然后如果实参也是宏,则展开实参;

最后再继续处理宏替换后的宏文本,若宏文本也包含宏则继续展开,否则完成展开。

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; }

?二分法。逻辑分析参考http://wjboy49.iteye.com/blog/695395

==========================================================================

7.fun(void)和fun()区别:

? ?在C++中无区别,均表示函数fun不接受任何参数,fun(a)因无法编译而报错。而在C中,若定义fun(void)则fun(a)因无法编译而报错,而定义fun()则fun(a)可编译运行。

============================================================================

8.以下程序输出为0 ? 1095237632

  int main()  {   float a = 12.5;   printf("%d\n", a);   printf("%d\n", *(int *)&a);   return 0;  }

?原因:%d 按照十进制整数打印;%6d 按照十进制整数打印,至少6个字符宽;%f 按照浮点数打印;%6f 按照浮点数打印,至少6个字符宽;%.2f 按照浮点数打印,小数点后有两位小数;%6.2f 按照浮点数打印,至少6个字符,小数点后有两位小数。

?

?

?

读书人网 >编程

热点推荐