有趣的C语言问题 测试你对C语言的熟悉程度
icon2 Program Impossible | icon4 2008-02-03 21:35| icon336 Comments | 本文内容遵从CC版权协议 转载请注明出自matrix67.com

下面这个程序输出什么?
enum {false,true};
int main()
{
        int i=1;
        do
        {
                printf("%d\n",i);
                i++;
                if(i < 15)
                        continue;
        }while(false);
        return 0;
}


你相信么?下面这个程序输出的两行东西不一样!
  #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;
  }


下面的程序看似完全正确。你能看出它为什么通不过编译吗?
看出问题前不要去试着编译,不然你会后悔你没看出来这个低级的语法错误。
#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;
}


为什么下面这个程序的输出不是NONE?看你多久才能看出来。
  #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;
  }


下面这个程序输出什么?
#include <stdio.h>
int main()
{
        int i=43;
        printf("%d\n",printf("%d",printf("%d",i)));
        return 0;
}


下面这个程序输出什么?
  #include<stdio.h>
  int main()
  {
      int a=1;
      switch(a)
      {   int b=20;
          case 1: printf("b is %d\n",b);
                  break;
          default:printf("b is %d\n",b);
                  break;
      }
      return 0;
  }


下面这个程序输出什么?
  #include <stdio.h>
  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;
  }


下面这个程序输出什么?
  #include <stdio.h>
  #include <stdlib.h>

  #define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))

  #define PrintInt(expr) printf("%s:%d\n",#expr,(expr))
  int main()
  {
      /* The powers of 10 */
      int pot[] = {
          0001,
          0010,
          0100,
          1000
      };
      int i;

      for(i=0;i<SIZEOF(pot);i++)
          PrintInt(pot[i]);
      return 0;
  }


下面这个程序输出什么?
  #include <stdio.h>
  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;
  }


下面这个程序输出什么?
#include <stdio.h>
int main()
{
        int i=23;
        printf("%d %d\n",i++,i++);
        return 0;
}


为什么下面这个程序的输出不是10?我故意取消了语法高亮:)
  #include <stdio.h>
  #define PrintInt(expr) printf("%s : %d\n",#expr,(expr))
  int main()
  {
      int y = 100;
      int *p;
      p = malloc(sizeof(int));
      *p = 10;
      y = y/*p; /*dividing y by *p */;
      PrintInt(y);
      return 0;
  }


下面这个程序输出什么?
  #include <stdio.h>
  int main()
  {
      int i = 6;
      if( ((++i < 7) && ( i++/6)) || (++i <= 9))
          ;
      printf("%d\n",i);
      return 0;
  }


下面这段代码是否合法?
  #include <stdio.h>
  #define PrintInt(expr) printf("%s : %d\n",#expr,(expr))
  int max(int x, int y)
  {
      (x > y) ? return x : return y;
  }

  int main()
  {
      int a = 10, b = 20;
      PrintInt(a);
      PrintInt(b);
      PrintInt(max(a,b));
  }


这是什么意思?有什么潜在的问题?
  #define SWAP(a,b) ((a) ^= (b) ^= (a) ^= (b))

这是什么意思?
  #define ROUNDUP(x,n) ((x+n-1)&(~(n-1)))

一些C语言的教材上会给出一个很经典的宏定义
  #define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
但这种宏定义的方法存在不足之处,一旦遇到下面这种情况就出问题了:
  char c;
  /* ... */
  if(isupper(c++))
  {
      /* ... */
  }

为了避免这种问题,应该怎样来定义isupper?


怎样用printf函数打印"I can print %"?别忘了百分号是用于格式化输出的。
不用任何比较运算符,写一个程序找出三个数中的最小数。
不用+号,(用位运算)实现加法运算。

最有趣的一个问题:不用分号,写一个Hello World程序。
这是有可能的,而且办法非常简单,只用到了最基本的语法规则。
实在想不出来再看答案吧(白色的):
#include <stdio.h>
int main()
{
    if (printf("Hello World")){}
}


查看更多:http://www.gowrikumar.com/c/

36 条回复

  • 楼层: 沙发 | | Exile 说:

    sofa....

  • 楼层: 板凳 | | Nova 说:

    我的沙发……就这么消失了……

  • 楼层: 地毯 | | 匿名龙神号 说:

    初学C++语言,完全不懂printf函数……

  • 楼层: 地板 | | bear 说:

    差点都没做对

  • 楼层: 地下室 | | c 说:

    把这些拿去作C语言考题就有意思了

  • 楼层: 地基 | | betaver 说:

    代码不高深~不过看得太费脑子了~
    记得有本老外写的书,专门讲C++程序的趣事,这样的代码有半本书...

  • 楼层: 地壳 | | Harok 说:

    联想到了面试[muteness]

  • 楼层: 地幔 | | 袁哲 说:

    怎么不能编译?
      #include<stdio.h>
      int main()
      {
          int a=1;
          switch(a)
          {   int b=20;
              case 1: printf("b is %d\n",b);
                      break;
              default:printf("b is %d\n",b);
                      break;
          }
          return 0;
      }

  • 楼层: 地核 | | Satily 说:

    第11个程序因为这一句:
    y = y/*p; /*dividing y by *p */;
    之中的
    y/*p
    中的 “*”“/”之间没有空格,所以会被误认为是注释~~~~

    很经典的问题~~~~

  • 楼层: 10楼 | | haha 说:

    enum {false,true};
    int main()
    {
            int i=1;
            do
            {
                    printf("%d\n",i);
                    i++;
                    if(i < 15)
                            continue;
            }while(false);
            return 0;
    }

    原来continue可以和break干相反的事:)

  • 楼层: 11楼 | | ping 说:

    最后那个问题其实最简单

    #include <stdio.h>
      int main()
      {
          while(printf("Hello world!")==1){}
      }

    因为scanf和printf都有返回值~直接输出即可;

  • 楼层: 12楼 | | multiple1902 说:

    怎么不能编译?
      #include<stdio.h>
      int main()
      {
          int a=1;
          switch(a)
          {   int b=20;
              case 1: printf("b is %d\n",b);
                      break;
              default:printf("b is %d\n",b);
                      break;
          }
          return 0;
      }

    注意语气……我以为是反问……

    晕刚才写验证码38+25我填了3825……

  • 楼层: 12a楼 | | ping 说:

    不用任何比较运算符,写一个程序找出三个数中的最小数。

    哈哈

    #include <stdio.h>
    #include <stdlib.h>

    int max(const void *a,const void *b)
    {
        int ta=*(int *)(a);
        int tb=*(int *)(b);
        return ta-tb;    
    }

    int main(void)
    {
        int a[]={3,2,1};
        qsort(a,3,sizeof(int),max);
        printf("%d",a[0]);
        return 0;
    }

  • 楼层: 14楼 | | ping 说:

    怎样用printf函数打印"I can print %"?别忘了百分号是用于格式化输出的。

    这样行不?

    #include <stdio.h>

    int main()
    {
        char c='%';
        printf("I can print %c",c);
        return 0;
    }

  • 楼层: 15楼 | | ping 说:

    呵呵,问m牛一个有趣的问题,很经典~

    能不能写一个程序,让它输出这个程序本身的代码?

  • 楼层: 16楼 | | haha 说:

    #include <cstdio>
    using namespace std;int main(){char a[1000]="#include <cstdio>%c%cusing namespace std;int main(){char a[100]=%c%s%c;char quote=34,enter=13,lf=10;printf(a,enter,quote,a,quote);return 0;}";char quote=34,enter=13,lf=10;printf(a,enter,lf,quote,a,quote);return 0;}

  • 楼层: 17楼 | | dd 说:

    这些在我看来都是无意义的问题。在语言本身深入钻研从来就不是好主意。

    回复:其实,我很同意

  • 楼层: 18楼 | | Satily 说:

    这些在我看来都是无意义的问题。在语言本身深入钻研从来就不是好主意。

    I agree~~~~

    这些程序一般都是程序员们无聊的时候自娱自乐用的~~~~一般没什么意义,不过找Bug是很有意思的事情~~~~

    这大概是学C的好处的其中一条~~~~[razz]

  • 楼层: 19楼 | | sqybi 说:

    这些在我看来都是无意义的问题。在语言本身深入钻研从来就不是好主意。

    只不过是消遣而已...干什么这么认真呢?

  • 楼层: 20楼 | | LuoboTixS 说:

    @ping:我记得近几年的IOCCC有过这样的作品.

  • 楼层: 21楼 | | 独孤 说:

    怎样用printf函数打印"I can print %"?别忘了百分号是用于格式化输出的。

    printf("%%");
    不是就行了

  • 楼层: 22楼 | | dahe_1984 说:

    看来c语言很受欢迎啊[heart]

  • 楼层: 23楼 | | dahe_1984 说:

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

    这个输出好象一样啊

  • 楼层: 24楼 | | dahe_1984 说:

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

    switch中编译时不检查均不匹配的情况,数字1都可以通过编译.

  • 楼层: 25楼 | | dahe_1984 说:

    #include<stdio.h>
      int main()
      {
          int a=1;
          switch(a)
          {   int b=20;
              case 1: printf("b is %d\n",b);
                      break;
              default:printf("b is %d\n",b);
                      break;
          }
          return 0;
      }

    这个有意思,赋值和不赋值一样了!

  • 楼层: 26楼 | | dahe_1984 说:

    收益了,现在公司面试就喜欢出这种的题目.回字有几种写法要搞清

  • 楼层: 27楼 | | dahe_1984 说:

    #define PrintInt(expr) printf("%s : %d\n",#expr,(expr))

    这里面预定义后面的# 和 括号怎么理解啊?[stun]

    回复:#表示把它当成字符串插入

  • 楼层: 28楼 | | 林健的BLOG » Blog Archive » sizeof的一些牛角尖问题 说:

    [...] sizeof的一些牛角尖问题 02月 15, 2009 | 4:08 pm分类:Linux与开源 | 标签:C语言sizeof编译器 | 2次阅读   昨天看了一些C语言问题(http://www.gowrikumar.com/c/)以及国内几个Geeks的解答(http://wangcong.org/blog/?p=291,http://www.matrix67.com/blog/archives/429),看来自己的C基础还是可以的,没遇到什么大问题。有时候自己也去分析过IOCCC(http://www.ioccc.org/)的代码,或多或少可以学到一些东西。尽管听起来都像是“‘回’字有四样写法”的那样。   说几条我最近想到的问题及其解答,都是关于sizeof的:   1、sizeof(i++)之后,i的值会怎样?答案是不变。记得大一初学C语言时想研究一下sizeof与函数有什么区别,得到的结果只是一些语法上的差别;学了汇编之后看看编译器生成的代码,才发现sizeof在编译时直接给定了一个常值,而非在运行时求值。进而又分析过sizeof(表达式)的结果,清楚了类型提升原理。但我之前没有注意过表达式中出现副作用的问题,于是在sizeof(i++)的问题上犹豫了。现在经过查阅资料和实验,结论是:sizeof在大多数情况下是编译时定值的,表达式中的任何副作用(包括有副作用的运算符、函数调用等)都不会发生。这里说“大多数情况”,排除了针对C99的新特性——不定长数组(variable length array)的特例。参考这篇文章(http://rednaxelafx.javaeye.com/blog/225909),如果sizeof运算符的参数是一个不定长数组,则该需要在运行时计算数组长度。   2、sizeof(’a')的结果是多少?这个要看是在C中还是C++中了。根据标准的规定,在C的算术类型提升时,字符常量’a'自动提升为整型,故结果是4(对于32位机器);而在C++中则有字符常量的规定,’a'就是一个单字节的字符常量,故结果是1。我这样理解:C强调了char的“数”属性,而C++强调了char的“字符”属性。   3、sizeof(’ab’)的结果又是多少?’ab’这种语法我以前没有注意到。经查,这叫做“多字节字符常量”(multi-character character constant),它限制在单引号中包含2至4个字节。根据标准,多字节字符常量的语义由编译器的实现决定。在我测试的gcc 4.0和VS2008中,如果int a = ‘abcd’,则a == 0×61626364。sizeof(’ab’) == sizeof(’abc’) == sizeof(’abcd’) == 4。   4、那么sizeof(L’a')呢?虽然wchar_t是在源代码级可移植的宽字符,但其大小依赖于操作系统或编译器的定义。独立出现的wchar_t常量并不会像char常量那样做算术提升,所以sizeof(L’a')就等于sizeof(wchar_t)。在我在32位Windows和Linux平台下分别为4和2。   5、至于sizeof(L’ab’)、sizeof(L’中’)、sizeof(L’中国’)又会如何?宽字符常量的单引号中出现多个字节构成的单个字符(如L’中’)是合法的,对它取sizeof,结果等于具体实现下的sizeof(wchar_t)。但出现多个字节构成的多个字符(如L’ab’、L’中国’)则是没有定义的,编译器可能报错,也可能给出不同的实现。在我测试的gcc4.0和VS2008中,L’abcd’分别返回了0×64和0×61。对它们取sizeof,结果等于具体实现下的sizeof(wchar_t),但注意这是标准未定义的,不应该确信。   这些东西在现实的工程中很少用到,毕竟自己写代码的时候都偏向于保守的、确保清晰而正确的方法。但在求职面试之类的场合,sizeof还是一个比较重要的考点,钻一钻牛角尖是值得的。 [...]

  • 楼层: 29楼 | | 强风 说:

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

    这个一直搞不懂饿,尽管知道了#和##的含义。应该怎么理解啊??大牛?

  • 楼层: 30楼 | | 洱海 说:

    29楼
    #定义会立即字符串化宏参数,不进行进一步的展开了
    所以g不用展开了,而h需要进一步展开

  • 楼层: 31楼 | | 晓而不羽 说:

    貌似 (a>b) 可以用 (abs(a-b)+(a-b)) 来替代

  • 楼层: 32楼 | | FALLEN DEVIL 说:

    mark

  • 楼层: 33楼 | | bg 说:

    if (a > b)可以替换为
    if (((b - a) & ~(~0U >> 1)))

  • 楼层: 34楼 | | xxx 说:

    膜拜大神的路过

  • 楼层: 35楼 | | C8LUKA 说:

    #include
    #ifndef __cplusplus
    enum bool {true,false};
    #endif
    using namespace std;

    int main()
    {
    int i=1;
    do
    {
    printf("%d\n",i);
    i++;
    if(i < 15)
    continue;
    }while(false);
    return 0;
    }

  • 楼层: 36楼 | | C8LUKA 说:

    用不了???

您也随便说几句吧:

您可以在 Gravatar 设置您的头像。