几个需要引起注意的面试题

1、如何判断一段程序是由C编译程序还是由C++编译程序编译的?

答案:C++编译时定义了_cplusplusC编译时定义了_STDC_

------------------------------------------------------

2、在C++程序中调用C编译器编译后的函数,为什么要加extern  “C” ?

答案:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。如假设某个函数原型为:void foo(int x,int y),则该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。因此C++提供了C连接交换指定符号extern “C”来解决名字匹配问题。

------------------------------------------------------

3main主函数执行完毕后,是否可能会再执行一段代码?给出说明。(美国某著名网络开发公司2005年面试题)

答案:如果需要加入一段在main函数退出后执行的代码,可以使用atexit()函数注册一个函数,代码如下:

#include

#include

int atexit(void (*function)(void));

void fn1(void), fn2(void), fn3(void), fn4(void);

int main()

{

    atexit(fn1);

    atexit(fn2);

    atexit(fn3);

    atexit(fn4);

    printf("This is executed first./n");

    return 0;

}

 

void fn1()

{

    printf("next./n");

}

 

void fn2()

{

    printf("executed ");

}

 

void fn3()

{

    printf("is ");

}

 

void fn4()

{

    printf("This ");

}

------------------------------------------------------

上述程序运行后的结果为:

 

 

显然出现上述结果的关键是函数atexit(),下面介绍下atexit()函数:   

  atexit函数的功能是注册终止函数,函数原型为int atexit(atexit_t func);

需要注意的是atexit()注册的函数类型应为不接受任何参数的void函数,exit调用这些注册函数的顺序与它们登记时候的顺序相反,即atexit是注册后进先出的函数,和函数入栈出栈是一样的。实际上这个过程也不完全算main执行完毕后还能执行代码,因为exit的过程仍处于main结束的过程中。

 上述程序中atexit注册了四个函数,理解为入栈的顺序为fn1()-> fn2()-> fn3()-> fn4(),因此出栈的顺序正好相反,而什么时候出栈呢?就是在调用函数结束时,准确的说应该是函数调用的最后的操作就是出栈过程。main()同样也是一个函数,在结束时,按出栈的顺序调用四个函数,即为fn4()-> fn3()-> fn2()-> fn1();注册这个函数的目的就是为了在函数退出时调用的,即使是main()函数也是这样的。可以在这些函数中加入一些清理工作,比如内存释放等等。

 

  其实进程的终止方式有8种,分别是(1)从main返回;(2)调用exit;(3)调用_exit_Exit;(4)最后一个线程从启动例程返回;(5)最后一个线程调用pthread_exit;(6)调用abort;(7)接到一个信号并终止;(8)最后一个线程对取消请求作出响应。其中前5种是正常终止,后3种是异常终止。

 

 

 

 

 

参考资料

[1]《程序员面试宝典》

[2] http://baike.baidu.com/view/653930.htm

[3] http://topic.csdn.net/u/20090821/08/d7f9c585-4d92-4f74-826c-0197996b7e17.html

你可能感兴趣的:(C/C++程序设计)