注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

The Bloom of Youth

本博客已搬家至http://kuangqi.me

 
 
 

日志

 
 

C语言基本功测试题,欢迎各路大虾挑战~  

2012-09-28 21:43:09|  分类: 编程之美 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
近来项目组经常讨论到一些C语言的基础问题,深感我们对这个基础的语言掌握的其实并不深入。我们也许只是那它描述简单的算法,然而C语言能做的不止那么多。读一读一些著名的开源项目的代码,你就发现其开发者对C语言特性的纯熟运用是抱着课本的我们根本无法想象的。转眼也大四了,各种招聘信息也纷至沓来,其中最常见的要求无非就是“熟练使用C/C++”,那到底对C语言有怎样的了解,才能算是“熟练”呢?

笔者结合自己的开发经验和读过的一些书,包括曾经被别人问过和问过别人的问题,总结出了13道C语言基本功测试题,并给出了解答。供初学者学习,供同一战线上的程序猿探讨,供各路大虾BS。

1. 在C语言的国际标准ISO/IEC 9899: TC3中,规定了标准库由24个头文件构成。请写出除了stdio.h, stdlib.h, string.h, math.h以外的20个头文件(5分—每写出一个得到1分,写出5个以上即得满分)

2. 程序填空,实现strcpy函数(5分)
char * strcpy(char *d, const char *s)
{
while(____________);
return src;
}

3. 假设a是int型,b是double型,下列哪句是正确的?(5分)
A.scanf(“%d,%f”, &a, &b); B.scanf(“a=%d b=%*f”, &a, &b); 
C.scanf(“%d%*lf”, &a, &b); D.scanf(“%d%*lf”, &a );     E. 以上都不对

4. sizeof("%%\\13%dxyz")的值是?(5分)

5. 定义int a=12; 则表达式 a += a -= a *= a; 的值为?(5分)

6. 假设下列程序运行在32位的计算机上
#include <stdio.h>
typedef union
{
int x;
char y[2];
}foo;

struct
{
double i;
char j[7];
foo f1;
}bar;

int main()
{
printf("%d, %d\n", (int)sizeof(foo), (int)sizeof(bar));
return 0;
}

(1)写出运行结果(5分)
(2)出现这个结果的原因(5分)
(3)foo和bar这两个标识符有本质的区别,是什么?(5分)
(提示:foo a1;   union foo a2;   bar b1;  struct bar b2;这四个语句哪些可以编译通过,哪些不能编译通过)

7. static关键字是C语言中颇受争议的关键字,因为在两种情况下需要用到static关键字,而这两种情况毫无联系。请列出static关键字的两个作用。(5分)

8. 下面两则断言实现的是同样的功能,哪一种更好?为什么?(5分)
(1)assert(size <= MAXSIZE && width <= W && height <= H);
(2)assert(size <= MAXSIZE);
         assert(width <= W && height <= H);

9. 建立一个n层的int型二维阶梯形数组a(第二维的长度分别是1,2,3…n+1),n是int型变量,值为10。
提示:从include开始写,不要只写核心代码。使用C语言。
(1)写出程序代码(10分)
(2)sizeof(a)的值是多少?(5分)

10. 阅读下列程序
int main()

{

        char *  p = NULL;

        char ** pp = NULL;

        const char *   pc  = p;    /* 第一处 */

        const char ** ppc = pp; /* 第二处 */ 

        char *   const cp  = p;    /* 第三处 */

        char ** const cpp = pp; /* 第四处 */

}

(1)四处代码是否能通过编译?(5分)
(2)解释pc和cp中const关键字修饰的对象(什么是可以修改的?什么是const的?)(5分)

11. 指出下列代码的错误,错误可能只有一处,也可能不止一处。(10分)
  int main()
  {
      typedef char * pStr;
      char string[3] = "abc";
      const char *p1 = string;
      const pStr p2 = string;
      p1++;
      p2++;
  }

12. 求最大值和最小值是编程中常用的操作,通常有使用普通函数和宏函数两种做法
宏函数:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
普通函数:
int min(int a, int b)
{
    return a <= b ? a : b;
请分析两种实现的优劣(10分)
(提示:从生成的代码长度、执行效率、适用范围和正确性等方面考虑。)

13. volatile关键字的含义是什么?使用volatile修饰的变量在编译时和运行时会表现出哪些特殊的行为?这个关键字通常用在哪些情况下?请至少举出一个例子。(5分)

答案:
1. The standard headers are
<assert.h>
<complex.h>
<ctype.h>
<errno.h>
<fenv.h>
<float.h>
<inttypes.h>
<iso646.h>
<limits.h>
<locale.h>
<math.h>
<setjmp.h>
<signal.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
<stdio.h>
<stdlib.h>
<string.h>
<tgmath.h>
<time.h>
<wchar.h>
<wctype.h>

2. 填空:*d++ = *s++;

3. D,*表示跳过参数

4. 11

5. 不确定,根据国际标准附录,在一个表达式中超过2次更改一个变量的值,则此行为由编译器实现定义(Implementation-defined behavior)

6. (1)输出4, 24
(2)由内存对齐导致。都与8字节的double进行对齐。
(3)foo是类型,bar是标识符。四个语句中只有foo a1;可以编译通过。我们无法在主函数中创建另外一个结构体变量,因为声明的结构体是匿名的。

7. (1)全局作用域下将变量定义到静态区,初始化成0。(1分)块作用域下也是如此,只初始化一次。与auto关键字相对(1分)
    (2)另外一个完全不同的功能是,表示该变量只能在该文件中访问。与extern关键字相对。(3分)

8. 第二种更好,将断言分开写可以在发生断言失败时报出准确的断言失败错误,而不是一堆组合,不知道是其中的哪一个出错了。

9.   (1)答案是:
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 int main()
  4 {   
  5     int i, n = 100;
  6     int **a = (int**)malloc(n * sizeof(int));
  7     for(i = 0; i < n; i++)
  8     {   
  9         a[i] = (int*)malloc((i+1)*sizeof(int));
 10     }
 11 }
(2)长度为指针的长度,32位机器上是4,64位机器上是8. 

评分标准:没包含stdlib.h的扣一分,i的声明写在for小括号中的扣一分,用new关键字而不用malloc的扣1分。指针操作或者强制类型转换有错误的直接扣10分。

10. (1)第二处在C编译器中会产生警告,C++编译器会产生错误。(2分)因为char**与const char**是不相容的。(3分)
(2)pc是一个指向字符常量的指针,自己本身可以修改(指向别的字符常量)
cp是一个常量指针,指向一个字符(不能指向别处,但指向的内存区域可以被修改)

11. string下标越界(2分), p2++操作不能通过编译,因为p2是只读的(8分)

12. 适用性:宏函数的优点是可以兼容各种类型,而int只能兼容整型(1分)
生成代码大小:宏函数会在每个调用的地方展开,而函数的代码只出现一次,如果调用次数较多的话,故普通函数代码会更小(2分)
执行效率:省去了栈操作,宏函数的执行效率更高一些(2分)
正确性:普通函数传值调用,任何情况下都是正确的。而宏函数在参数包含自增或者自减运算时,不能保证正确。例如MIN(a++, b)时,a会被自增两次。(5分)

13. volatile意为“易变的”,这个关键字表示变量很可能在别处被改变。(1分)由volatile修饰的变量,在编译时编译器不会对其进行优化,在运行时,每次访问该变量都会读取RAM中实际的值,而不会使用寄存器或者cache中缓存的值。(2分)volatile通常应用有:(1)分布式应用,多机并行 (2)多线程应用 (3)底层应用中可能被中断服务程序(ISR)修改的变量(2分,答出一条即可)
  评论这张
 
阅读(1268)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017