C++笔试和面试题

12.请完成以下题目。注意,请勿直接调用 ANSI C 函数库中的函数实现。

 a)请编写一个 C 函数,该函数给出一个字节中被置 1 的位的个数,并请给出该题的至少一个不同解法。

第一种unsigned   int   TestAsOne0(char   log)   
  {   
          int   i;   
          unsigned   int   num=0,   val;   
          for(i=0;   i<8;   i++)   
          {   
                  val   =   log   >>   i;     //移位
                  val   &=   0x01;     //1相与
                  if(val)   
                          num++;   
          }   
          return   num;   
  }  

第二种unsigned   int   TestAsOne1(char   log)   
  {   
          int   i;   
          unsigned   int   num=0,   val;   
          for(i=0;   i<8;   i++)   
          {   
                  val   =   (~log)   >>   i;   //反码? 
                  val   &=   0x00;           //0相与
                  if(!val)   
                          num++;   
          }   
          return   num;   
  }  

   b)请编写一个 函数,该函数将给定的一个字符串转换成整数。

int Invert(char *str) 

int num=0; 

while(*str!='\0') 

int digital=*str-48; 

num=num*10+digital; 

str=str+1; 

return num; 

   c)请编写一个 函数,该函数将给定的一个整数转换成字符串。

void   IntToCharChange(int   num,   char*   pval)   
  {   
        char   strval[100];   
          int   i,   j;   
          int   val0   =   0;   
          int   val1   =   0;   
            
          val0   =   num;           
          for(i=0;   i<100;   i++)   
          {   
          val1   =   val0   %   10;   //取余
          val0   =   val0   /   10;   //取整
          strval[i]   =   val1   +   48;  //数字字符 
          if(val0   <   10)   
          {   
          i++;   
          strval[i]   =   val0   +   48;   
          break;   
          }   
          }   
          for(j=0;   j<=i;   j++)     //倒置
          {   
          pval[j]   =   strval[i-j];   
          }   
          pval[j]   =   '\0';   
  }

   d)请编写一个 函数,该函数将一个字符串逆序。

void   AntitoneValue(char*   father,   char*   child)   
  {   
  int   i;   
          char   source[100];   
  int   j   =   0;   
    
  while(father[j])     //放入source[j]为长度
  {   
  source[j]   =   father[j];   
  j++;   
  if(j   >   99)   
  {   
  return;   
  }   
  }   
  source[j]   =   '\0';   
    
  for(i=0;   i<j;   i++)   
  {   
  child[i]   =   source[j-i-1];     //反序
  }   
  child[i]   =   '\0';   
  }  

e)请编写一个 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。

int search(char *cpSource, int n, char ch)  //起始地址,搜索长度,目标字符
{
int i;
for(i=0; i<n && *(cpSource+i) != ch; ++i);
return i;
}

   f)请编写一个 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。

int  ChildString(char*p)     //自己写

  {   

  Char *q=p;

int  stringlen=0, i=0,j=1,len=0,maxlen=1;   

while(*q!=’\0’)          //不能用strlen,求得长度stringlen

{

  Stringlen++;

q++;

}

  while( i< Stringlen )   

  {   

  if(*(p+i)==*(p+j)&&j< Stringlen)   

  {   

  len++;                    //统计子串长度

  i++;

  j++;   

  }   

  else   

  {   

  if(len>maxlen)           //统计最大子串长度

  {   

  maxlen=len+1;   

  len=0;

  }  

  else {

  len=0;

       }   

       i++;

   j++;

                   

  }   

  }  

  return   maxlen;   

}   

给出演示上述函数功能的一个简单程序,并请编写对应的 Makefile 文件

13.我们需要编写一个图形相关的应用程序,需要处理大量图形(Shape)信息,图形有矩形(Rectangle),正方形(Square),圆形 (Circle)等种类,应用需要计算这些图形的面积,并且可能需要在某个设备上进行显示(使用在标准输出上打印信息的方式做为示意)

    a)请用面向对象的方法对以上应用进行设计,编写可能需要的类

    b)请给出实现以上应用功能的示例性代码,从某处获取图形信息,

      并且进行计算和绘制

    c)如果你的Square继承自Rectangle,请给出理由,如果不是,

      请给出理由,并且请比较两种方式的优劣

    d)请问你所编写的类,在如下代码中会有何表现,请解释

    void test_rectangle_area(Rectangle& r)

    {

        r.set_width(10);

        r.set_height(15);

        assert(r.area() == 150);

}

14.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节

点不是尾节点,试编程实现删除此节点

参考:将下一个节点的内容复制到本节点上,然后删除下一个节点;

15.写一个程序,把一个100以内的自然数分解因数。(自然数分解因数就是将一个自然数

分解为几个素数的乘积,提示,由于该数不是很大,所以可以将质数保存在数组中,以加快计

算速度)

16.编写一个Identify的分配、释放的函数,为110000之间的自然数。

17.分别实现itoaatoi.

#include<stdio.h>
int atoi(const char *str)
{
 int value=0;
 bool b_plus=true; //判断符号

 switch(*str) //过滤符号

 {
 case '+':
 str++;
 break;
 case '-':
 b_plus=false;
 str++;
 break;
 default:
 break;
 }

 while('\0' != *str)
 {
 value = (value*10)+(*str-'0');
 str++;
 }
 if(!b_plus)
 value=-value;
 return value;
}

void main()
{
 char str[]="-999";
 int value=atoi(str);
 printf("The result is:%d\n",value);
}

(2)itoa的实现:

#include<stdio.h>
void itoa(int value, char *str)
{
 if (value < 0) //如果是负数,str[0]='-',并把value取反(变成正整数)

 {
 str[0] = '-';
 value = 0-value;
 }
 int i,j;
 for(i=1; value > 0; i++,value/=10) //value[1]开始存放value的数字字符,不过是逆序,等下再反序过来

 str[i] = value%10+'0'; //将数字加上0ASCII('0')就得到该数字的ASCII

 for(j=i-1,i=1; j-i>=1; j--,i++) //将数字字符反序存放

 {
 str[i] = str[i]^str[j];
 str[j] = str[i]^str[j];
 str[i] = str[i]^str[j];
 }
 if(str[0] != '-') //如果不是负数,则需要把数字字符下标左移一位,即减1

 {
 for(i=0; str[i+1]!='\0'; i++)
 str[i] = str[i+1];
 str[i] = '\0';
 }
}

void main()
{
 int value = -1212345;
 char str[10] = {'\0'}; //记得把str全填充为'\0'

 itoa(value, str);
 printf("The result is:%s\n", str);
}

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("%d\n", 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越界,0buf开始的第4(0开始)个字节覆盖掉了.x86LSB排列顺序,所以真好覆盖了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=%d\n",b); 

}

21.有双向循环链表结点:(华为面试题)

typedef struct node

{

  int date;

  struct node *front,*next;

}_Node;

有两个双向循环链表AB,知道其头指针为: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"  是常量字符串,存储在全局变量区,和静态变量一起。即不在堆,也不在栈   在程序结束时自动释放    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值