C++笔试题老题重发(3)

匿名网友 匿名网友 发布于: 2015-08-30 00:00:00
阅读 139 收藏 0 点赞 0 评论 0

16.编写一个Identify的分配、释放的函数,为1-10000之间的自然数。
17.分别实现itoa和atoi.

18.Consider the following code:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int i = 1;
char buf[4];
strcpy(buf, “AAAA”);
printf(“%dn”, i);
return 0;
}

a) When compiled and executed on x86, why does this program usually not output what the programmer intended?     在x86上为什么不能得到预期结果

b) Name several ways in which the security problem that causes this program not to output what the programmer intended can be prevented WITHOUT changing the code.

参考:第一个问题:  
  32位情况:  
  x86下,栈方向向上生长.在main的栈中,先分配i空间(4byte),然后分配4个字节的buf(地址在i的上面,比i小).strcpy越界,用0把buf开始的第4(0开始)个字节覆盖掉了.而x86是LSB排列顺序,所以真好覆盖了i的内个数字1.所以显示出数字0.  
  16位情况同样分析即可. 
第2问?

19.int w=1,x=2,y=3,z=4;
m=(w<x)?w:x;
m=(m<y)?m:y;
m=(m<2)?m:z;
printf(“m=%d”,m);        说出结果
答案:1

20.说出结果   ???
#include <stdio.h>
main()
{
    FILE *fp;
    int i,a[4]={1,2,3,4},b;
    fp=fopen(“data.dat”,”wb”);//这里帮忙解释一下
    for(i=0;i<4;i++)
    fwrite(&a[i],sizeof(int),1,fp);//这里也帮忙看一下
    fclose(fp);
    fp=fopen(“data.dat”,”rb”);
    fseek(fp,-2L*sizeof(int),SEEK_END);//还有这里
    fread(&b,sizeof(int),1,fp);//这里还有也看一下
    fclose(fp);
    printf(“b=%dn”,b);
}
21.有双向循环链表结点:(华为面试题)
typedef struct node
{
  int date;
  struct node *front,*next;
}_Node;
有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两上链表中date值相同的结点删除
参考算法:      
  1.取出A的一个元素d  
  2.收集B中有相同元素d的结点到垃圾箱,并从B里删除  
  3.收集A中有相同元素d的结点到垃圾箱,并从A里删除  
  4.删除垃圾箱中的所有元素  
  5.A链的指针指向下一个  
  6.重复1~5,直到A链循环到头了  
  注意的是第3步,在2步执行后垃圾箱不为空时才执行。 
上述算法还可以做一点点优化:  
  1.加入两个变量cA,   cB,分别记录当前A中和B中的元素个数  
  每次从较长者中取出一个元素来,先从较小者中找起  
  若没有,则不必在较长者中浪费时间了
#include<iostream.h>     ?
  struct   NODE  
  {  
      int   date;  
      NODE   *front,*next;  
  }; 
void   redel(NODE   *&ahead,NODE   *&bhead)  
  {  
          int   boy=0;  
          NODE   *pa=ahead,*pb=bhead,*paa,*paaa,*paaaa,*pbb;  
          while(pa->next!=ahead)  
          {  
                  int   boys=pa->date;   //取pa中一个值
                  paaaa=pa;  
                  paa=pa;  
                  pb=bhead;  
                  while(pb->next!=bhead)  
                  {  
                          if(boys==pb->date)   //如果pa,pb中有值相同
                          {        
                                  cout<<endl;  
                                  cout<<“delete   B:”<<paa->date<<”   “;  
                                  if(pb==bhead)  
                                  {  
                                          boy=1;  
                                          pb->front->next=pb->next;  
                                          pb->next->front=pb->front;  
                                          bhead=bhead->next;  
                                          pbb=pb;  
                                          pb=pb->next;  
                                          delete   pbb;  
                                  }          
                                  else  
                                  {  
                                          boy=1;  
                                          pb->front->next=pb->next;  
                                          pb->next->front=pb->front;  
                                          pbb=pb;  
                                          pb=pb->next;  
                                          delete   pbb;  
                                  }  
                          }  
                          else  
                                  pb=pb->next;                
                  }  
                  while(paa->next!=ahead   &&   boy==1)  
                  {          
                          if(paa->date==boys)  
                          {        
                                  cout<<“delete   A:”<<paa->date<<”   “;  
                                  if(paa==pa)  
                                  {  
                                          pa=pa->next;  
                                          ahead=pa;  
                                          paa->front->next=paa->next;  
                                          paa->next->front=paa->front;  
                                          paaa=paa;  
                                          paa=paa->next;  
                                          delete   paaa;  
                                  }          
                                  else  
                                  {  
                                          paa->front->next=paa->next;  
                                          paa->next->front=paa->front;  
                                          paaa=paa;  
                                          paa=paa->next;  
                                          delete   paaa;  
                                  }          
                          }  
                          else  
                          {  
                                  paa=paa->next;  
                          }          
                  }  
                  boy=0;  
                  if(paaaa==pa)  
                          pa=pa->next;  
          }  
          cout<<endl;                      
  }
int   main()  
  {  
          NODE   *A,*pHeadA,*B,*pHeadB;  
          A=new   NODE;  
          B=new   NODE;  
          pHeadA=A;  
          pHeadB=B;  
          for(int   i=1;i<21;++i)             //生成链表A,并赋初值!  
          {  
                  A->date=i;  
                  A->next=new   NODE;  
                  A->next->front=A;  
                  A=A->next;  
          }  
          A=A->front;  
          delete   A->next;  
          A->next=pHeadA;  
          pHeadA->front=A;  
           
          for(int   i=1;i<33;i+=2)         //生成链表B,并赋初值!  
          {  
                  B->date=i;  
                  B->next=new   NODE;  
                  B->next->front=B;  
                  B=B->next;  
          }  
          B=B->front;  
          delete   B->next;  
          B->next=pHeadB;  
          pHeadB->front=B;  
           
          redel(pHeadA,pHeadB);         //调用函数删除相同结点!  
  } 

22.
char * GetStr()
{
char *tmp;
tmp = “123”
return tmp;
}

void main()
{
printf(“%s”, GetStr());
}
会输出123吗?123创建在堆上还是栈上呢?123的空间是什么时候释放的?
参考:”123″  是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈   在程序结束时自动释放   

23.1)字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?为什么?
答案:指针变量也占用内存单元,而且所有指针变量占用内存单元的数量都是相同的。就是说,不管是指向何种对象的指针变量,它们占用内存的字节数都是一样的,并且要足够把程序中所能用到的最大地址表示出来(通常是一个机器字长)。

2)类ClassB从ClassA派生,那么ClassA *a = new ClassB(…); 试问该表达是否合法?为什
么?
答案:派生类的指针指向基类的对象是错误的,不能通过编译的; 基类的指针可以指向派生类的对象,调用派生类的函数
鸡是动物,没错。( 动物的指针 指向 鸡的实例)
鸡可以执行所有动物都具有的方法,例如 “死亡”
反过来,动物一定是鸡吗?(鸡的指针 指向 动物或者动物的某个派生类的实例)
动物都能执行鸡的某个方法吗?比如说 “下蛋”?

3)如果ClassA中定义并实现虚函数int func(void),ClassB中也实现该函数,那么上述变量
a->func()将调用哪个类里面的函数?如果int func(void)不是虚函数,情况又如何?为什
么?
答案:第一问调用的是B的。第二问调用A的。
虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果
如果没有定义成虚函数:——
class A{
public:
void print(){ cout<<”This is A”<<endl;}
};

class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}
};

int main(){   //为了在以后便于区分,我这段main()代码叫做main1
A a;  B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}
结果是两个This is A
如果定义成虚函数:———
class A{
public:
virtual void print(){ cout<<”This is A”<<endl;}  //现在成了虚函数了
};

class B:public A{
public:
void print(){ cout<<”This is B”<<endl;}  //这里不需要在前面加上关键字virtual,只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数
};
再运行main输出的结果就是This is A和This is B

测试:
4)char **p, a[16][8];  问:p=a是否会导致程序在以后出现问题?为什么?
参考: 这个不会导致出现问题,但是要注意p的使用,如a[1][2] 等价的为 *(*(p+1)+2)而不是*(p+11),
会的,这样会出现编译错误  正确的是:char a[5][5]; char (*p)[5]; p=a;

如下所述的if else和switch语句哪个的效率高?为什么?

5)在同一个进程中,一个模块是否可以通过指针操作破坏其它模块的内存,为什么?(华为)

6)应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?
参考:对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

评论列表
文章目录