12个有趣的C语言问答

0. gets() 方法

Q:以下代码有个被隐藏住的问题,你能找到它吗?

A:这个不显眼的问题就是使用了 gets() 方法。此方法接受一个string类型参数,但是却没有检测此数值是否 有足够的空间来拷贝数据。所以这里我们一般用 fgets() 方法将来的更好。

1,strcpy() 方法

Q:密码防护是很基本的功能,看看能否搞定下面这段代码?

2,main() 方法的返回类型

Q:请问下面这段代码能否通过编译?如果能的话,那么这段代码中隐含什么问题吗?

A:答案是代码能通过编译,但是会留下针对main()方法的返回类型的警告。main()方法的真正返回类型应该为’int’而非’void’。这是因为’int’返回类型能够让程序返回状态值。尤其是当这段程序作为其他应用的附属程序时这个状态值将更加重要。

3,内存泄露

Q:请问以下代码有内存泄露吗?

A:好,虽然上面的代码没有对指针 ptr 进行内存释放,但实际上即使是程序结束也不会造成内存泄露,因为当程序结束时所有一开始被占据的内存就全部清空了。但如果上面这段代码是在 while 循环里面那将会造成严重的问题

Note: 如果你需要了解更多关于内存泄露的问题以及如何使用工具检测内存泄露,你可以参考这篇文章 Valgrind

4,free() 方法

Q:以下代码当用户输入’freeze’时会奔溃,而如果输入’zebra’则运行正常,这是为什么?

A:问题的根源是因为代码在while循环中改变了 ptr 指针的地址。当输入为’zebra’时,while循环甚至在执行 第一遍前就结束了,所以free()释放的内存地址就是一开始malloc()分配的地址。但是当输入’freeze’时, ptr记录的地址在while循环中被更改,因为将会是错误的地址传递到free()方法中引起崩溃。

5,atexit with _exit

Q:在以下代码,atexit()方法并没有被调用,你知道为什么吗?

A:这是因为使用了 _exit() 方法。此方法并没有调用清除数据相关的方法,比如 atexit()等。

6,void* 与 C 结构体

Q:能否设计一个方法接受任意类型的参数然后返回整数?同时是否有办法传递多个这样的参数?

A:一个能接受任意类型参数的方法像下面这个样子:

如果需要传递多个参数,那么我们可以传递一个包含这些参数的结构体

7,* 与 ++ 操作符

Q:以下代码将输出什么?为什么?

A:以上的输出将是:

因为++与 * 的优先级一样,所以 *ptr++ 将会从右向左操作。按照这个逻辑,ptr++ 会先执行然后执行*ptr。所以第一个结果是’L’。也因为 ++ 被执行了,所以下一个printf() 结果是’i’。

8,Making changes in Code segment

Q:以下代码运行时一定会崩溃,你能说出原因吗?

A:这是因为,通过 *ptr = ‘T’,此行代码尝试更改只读内存存储的字符串’Linux’。此操作当然行不通所以才会造成崩溃。

9,Process that changes its own name

Q:你能否写一个程序在它运行时修改它的名称?

A:以下代码可以完成

A,局部变量的返回地址

Q:下面的代码有问题吗?如果有,如何修改?

A:虽然上面的代码有时运行会很好,但是在方法 inc() 中有很严重的隐患。当inc()方法执行后,再次使用局部变量的地址就会造成不可估量的结果。解决之道就是传递变量a的地址给main()。

B,处理 printf() 参数

Q:以下代码输出请问是什么?

A:输出将是

这是因为参数都是从右向左处理的,然后打印出来却是从左向右。

 

4 收藏 15 评论

相关文章

可能感兴趣的话题



直接登录
最新评论
  • 第8个问题,我在TC2.0编译下没有问题呀。。输出是[Tinux]。这篇文章。。。

    • TC2.0出来的时候C89的标准都没出来,所以TC2.0是不符合任何C语言标准的。学C语言,还是用新点的编译器吧~~

  • Strygwyr   2012/09/12

    第二个貌似是长度超过10位, 不管是不是“LinuxGeek", 就一直是破解成功了

    • Darkscope   2013/09/10

      strcpy把flag覆盖了,改成
      if(0 == strcmp("LinuxGeek", passwd))
      {
      flag = 1;
      }
      else
      flag = 0;
      就好了

  • magin   2013/08/05

    第七个例子其实不明显,不管优先级是怎么样的,结果都会是:Li

  • vinllen   2013/09/10

    求解第二问Answer 。。。自己试过 比9位长的也不行

    • MidoriYakumo   2015/05/30

      栈向下生长,flag声明在passwd前面, strcpy不安全,直接写到flag上面去了。

  • yingshin   2013/09/10

    strcpy() 方法
    这个只知道尽量用strncpy,谁能给详细解释下,我的直接出错退出了。

  • madoldman   2013/09/10

    最后一个是错的,C语言只规定了参数的压栈顺序,并没有规定参数的求值顺序

    • harder   2013/09/11

      我试了下,没错啊

      • 于小鱼   2014/06/02

        这叫做 undefined behavior, 即使你的编译器结果符合你的“预期”,也证明不了什么。永远不能依赖undefined behavior.

    • Yu_Hao 微信公众号: 一分钟的编程知识 2015/05/23

      再吐槽一句,说 “参数都是从右向左处理的,然后打印出来却是从左向右” 的, 估计是谭浩强的书学出来的吧。

  • 第十题Process that changes its own name

    运行后的进程名没有被修改啊,求解释。

  • Like   2013/09/17

    有翻译错误,把from当成to翻译了....:解决之道就是传递变量a的地址给main()。
    原文是:This can be avoided by passing the address of variable ‘a’ from main() and then inside changes can be made to the value kept at this address.
    正确的翻译是:从main()中传递变量a的地址给inc()。

  • LEI   2013/12/13

    我觉得第7题,应该是先执行 *ptr,再执行 ptr++,右结合可以看作是++对ptr结合,而不是对*ptr结合

跳到底部
返回顶部