程序员面试宝典

程序员面试宝典2008-10-05 22:27     第一部份 C/C++
一、i++

   1. x=x+1 , x+=1 ,x++ 那种效率最高 为什么?

   解析:
   
     x=x+1 效率最低
  
    因为它的执行过程如下:
     
     
       1.读取右边x的地址.
       2.x+1.
       3.读取左x的地址.
       4.将右值传给左边的X(编译器并不认为左右的X地址相同)
     
     
    其次 x+=1.
  
       1.读取右x的地址
       2.x+1
       3.将得到值传给x(因为x的地址已经读出)
     
    x++效率最高
  
       1.读取右x的址址
       2.x自增1
     
     
    
   2. What will be the output of the following C code?
 
    #define product(x)(x*x)
    int main()
    {
     int i=3,j,k;
     j=product(i++);
     k=product(++i);
     printf("j=%d,k=%d",j,k);
     return 0;
   
    }
  
    解析:
   
     product(i__)=i++*i++;i=3,所以j等到于9,此时i已经累加到5了.
     product(++i) 要求先累加i,累加后i等于7,所以product(++i)结果49;
  
    答案:9,49
 
   3.if there are "int a=5,b=3;",the values of a and b are ____ and ____ after execute "!a && b++;",
 
     解析:
     这是表达式运算问题.因为"!a"运算结束后,整个表达式的值已经为假,所以不必再去计算后面的式子.
   
     答案:5,3
   
二、编程风格

   1.we have two pieces of code,which one do you prefer ,and tell why?
 
    A .
     // a is a variable
  
    写法1:
   
     if('A'==a)
     {
      a++;
     }
    写法2:
     if(a=='A')
     {
      a++;
     }
   
    B .
    写法1:
     for(i=0;i<9;i++){
      X=i+Y+J*7;
      printf("%d",X);
     }
  
    写法2:
     S=Y+J*7;
     for(i=0;i<9;i++){
    
      printf("%d",i+S);
     }
   
    解析:
  
     A:第一种写法('A'==a)比较好,如果把"=="误写成了"="号,编译器会检查到此错误!
      因为编译器不允许给常量赋值;
    
     B:第二种写法好一些,将部份加法运算放到循环体外面,提高了效率.但代码不够简洁
   
三、类型转换

   1.char foo(void)
   {
    unsigned int a=6;
    int b=-20;
    char c;
    (a+b>6)?(c=1):(c=0);
    return c;
   }
    解析:unsigned int 类型的数据与int 类型的数据相运算后,自动转化为unsigned int类型
    所以a+b的值不为-14,而是一个unsigned int类型的大数4294967382
    因此返回值为1,与我们实际想要的结果不符,
    可以定义一个int 类型的变量来接收这个值,或者强制类型转换,才能达到我们想要的结果。
  
四、a,b交换

   1.There are two int variable:a and b,don't use "if" ," ? : ",switch,or other judgement statementes,
 
   find biggest one of the two numbers?
 
   答案
 
    方案1: int max=((a+b)+abs(a-b))/2;
 
    方案2: int c=a-b;
       char *strs[2]={"a大","b大"};
       c=unsigned(c) >> {sizeof(int)*8-1};
五、C++与C的关系?

   1.在C++程序中调用被C编译后的函数,为什么要加 extern "C" ?
 
   答案:C++中允许函数重载,而在C中不能,函数在C++中编译后和C中不同,所以
 
     C++提供了C连接交换指定符号 extern "c" 是为了解决名字匹配问题.
   2.头文件中ifndef/define/endif是干什么用的?
  
   答案:防止该头文件被重复使用.
  
   3. #include<stdio.h>与#include "stdio.h" 有什么区别?
 
   答案:前者是从标准库路径下寻找头文件,而后者是从用户工作路径下寻找头文件
  
   4.如何判断一个程序是由C还是C++编译的?
 
   答案: C++编译时定义了_cplusplus
     C编译时定义了_stdc_;
   
 

 

第六章 预处理、const与sizeof
1. 预处理当中的宏定义
注意:有时候宏展开以后会出现二意性问题。所以要注意使用括号。
2. sizeof的总结
sizeof是运算符,它的作用是返回一个类型或变量的长度,长度的单位是字节。
(1)基本数据类型sizeof的结果
平台:Windows XP,32位cpu;
* VC++6.0.

使用.c和.cpp作为文件后缀得到的结果是同样的.(有的程序同样是在VC++6.0下,后缀名不同,用的编译器不同,结果也不同。谭浩强的C语言第二版

上的有个union类型的例题就是这样,用.c就可以编译通过,用.cpp作为后缀,就有错误。)
* Turbo C下的结果是不相同的。int类型是2,long double是10.

(2)结构体的sizeof问题(数据对齐问题)
为了方便对结构体内元素的访问和管理,以结构体里面最长的数据元素的长度为对齐单位,也就是说,结构体的长度一定是最长元素的整数倍。(不

管结构体内的元素是大于还是小于处理器的位数)。这点跟书上的不同。书上的经过VC++验证,反正在VC++下是错的。并且最大的单位就是8个字节,

即使结构体中有其他结构体的变量,也最大是以8个字节为单位对齐的。8字节是基本数据类型中占空间最大的单位。
结构体内小于最长元素的元素,如果是单独的,则占用一个最长单位;如果有几个连续的放在一起的,可以按最长单位顺序存放。知道满了或者剩下

的不够超出为止,即换到下一个最长长度单位。
例1:
struct tagD
{
      short d1;
      double d2;
      short d3;
};
结果为:。以8个字节为单位,不足8的补齐。第一个short占2个,但是后面紧跟着是double占8个字节,所以让第一个short占8个字节,接下来double

再占8个字节。最后一个short一样处理,不足8补成8个字节。
例2
struct tagD
{
      double d2;
      short d1;
      short d3;
};
结果为: 。以8为单位,后面的两个short加起来只占4个,不够8个单位,所以一共是2个8字节,一共是16.
对于结构体中的位运算中的位段,是以4字节,即int所占字节的大小为单位对齐的。如果位段结构体中还有其他类型,那么同样是以最大字节数为对

齐单位。
(3)对类sizeof
1.       空类占1个字节;
2.       类中的成员函数不计算在内,只计算成员变量占多少个字节;
3.       静态成员变量不计算在内,因为静态成员变量存放在全局数据区,而sizeof是计算栈中分配的大小。
4.       如果有虚函数或者纯虚函数的话,不管有多少个,只增加4个字节,这四个字节是虚函数表的指针所占的空间。
5.       多重继承的话也不会增加所占字节数;
6.       虚继承,会增加4个字节。
7.       虚继承有虚函数的类,那么新类增加4+4个字节。如果自己还有虚函数,则再增加4个字节。
8.       但非虚继承有虚函数的类,新类增加4个字节,而且即使自己还有虚函数,也不再增加额外的4个字节。说明它们用的是同一个虚函数表。
(注)以上提及的增加,对于空类来说,只是由1个字节变为,而不是在1上增加。
例:
class A
{
};
class A2
{
};
class B
{
  void virtual funB();
};
class B2
{
      void virtual funB2()=0;
};
class C: public A
{
};
class D: public virtual A
{
};
class E: public A,public A2
{
};
class F1: public virtual B
{
};
class F2: public virtual B
{
void virtual funf(void);   //自己有虚函数,还会再增加4个字节。
};
class G1: public B
{
};
class G2: public B
{
      void virtual funH(void); //自己有虚函数,但不增加4个字节。
};

void main(void)
{

cout<<"class A: "< cout<<"class B(have virtual func): "< cout<<"class C(derived from A): "< cout<<"class D(virtual derived from A):

"< cout<<"class E(multiple derived from A and A2): "< cout<<"class F1(virtual derived from B,B have virtual func,F1 don't have

virtual func): "< cout<<"class F2(virtual derived from B,B have virtual func,F2 also have virtual func): "< cout<<"class G1(derived

from B,B have virtual func,G1 don't have virtual func): "< cout<<"class G2(derived from B,B have virtual func,G2 also have virtual

func): "< }

(4)对数组名sizeof(退化为指针的问题)
等于将其元素类型做sizeof的结果×数组元素的个数。
而当数组名作为函数参数时,有个退化的问题。即在函数内部用sizeof(数组名),则得到是一个指针的大小,即4字节,非上面数据类型×数组元素

的个数。
例:
char var[10];
int test(char var[])
{
return sizeof(var);
}
cout<<br /> cout<<br /> 返回的是4,而非10. 运行结果为:


第五章 程序设计基本概念
1.++运算符的顺序问题
#define product(X) (X*X)
void main()
{
 int i=3,j,k;
 j=product(i++);
 k=product(++i);
 printf("j=%d,k=%d",j,k);
 return
}
结果为j=9;k=49;已经在VC++6.0上验证;
注意:在一个表达式中,同时有1个以上的同一个变量的++运算符,进行+-*/运算的i的值是相同的。如果有++i,则i的值在运算前+1,如果有i++则在

做完运算后才去+1.
2. 类型转换char foo(void){      unsigned int a=6;      int b=-20;      char c;      (a+b>6)?(c=1):(c=0);      return c;}结果:返回

值为1.注意:1. 有符号整形与无符号型做运算的时候,有符号整形会自动转换成无符号的。2. 调用函数,实参形参类型不同,自动转换为形参类型

;3. 函数返回值类型与函数类型不同时,转换为函数类型;4. Doulbe ßfloat  (ß表示左边类型任何时候都会自动转换成右边的来进行运算)↑     

        (↑表示混合类型数据进行运算时,数据会自动向上面的类型转换)Long↑Unsigned int↑Int ßchar, short3. a和b求最大值的技巧算法

int max=((a+b)+abs(a-b))/2;注释:a+b再加上它们的差,即为max的两倍,处于2后就是最大的值;4. a和b交换的技巧算法a=a^b; b=a^b; a=a^b;注

释:无须 担心超界的问题。5. 如何判断一段程序是由C编译程序还是有C++编译程序编译的?答案:C++编译时在目标文件中定义了_cplusplus宏; C

编译时定义了_STDC_宏.6. main主函数执行完毕后,再执行一段代码的问题int main(void){      void fn1(void),fn2(void),fn3(void),fn4

(void);atexit(fn1);      atexit(fn2);      atexit(fn3);      atexit(fn4);      printf("The main function is running!/n");} void

fn1(void){      printf("next !/n ");}void fn2(void){      printf("executed ");}void fn3(void){      printf("is ");}void fn4(void){ 

    printf("This ");}注释:如果需要加入一段在main退出后执行的代码,可以使用atexit()函数注册一个函数。且先注册的后执行。7. C++程序中

调用被C编译器编译后的函数,要加extern “C”,用来解决名字匹配问题。注释: C++支持函数重载,C不支持。函数被C++和C编译后在库中的名字

不同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值