2016_2_28 c++能力评估20题

1.对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()

2.  
1
2
3
4
5
6
7
enum string{    
     x1,    
     x2,    
     x3= 10 ,    
     x4,    
     x5,    
} x;
函数外部问x等于什么?
  • 5
  • 12
  • 0
  • 随机值

enum只是定义了一个常量集合,里面没有“元素”,枚举类型是当做int类型存储的, sizeof值都为4 ,并且系统为其初始化为0;
但是在vs2015中,sizeof 值的确是4,但输出x报错: 使用了未初始化的局部变量“x”

3. 
1
2
3
4
5
6
7
8
9
10
11
12
  void  example( char  acWelcome[]) {
     printf ( "%d\n" sizeof (acWelcome));
     return ;
}
void  main() {
     char  acWelcome[] =  "Welcome to Huawei Test" ;
     example(acWelcome);
     cout <<  sizeof (acWelcome) <<  " "  <<  strlen (acWelcome) << endl;
     system ( "pause" );
     return ;
}

输出结果:4  23 22
32位系统是4 64位系统是8,数组作为函数的参数是会退化为函数指针的,想想看,数组作为函数参数的时候经常是需要传递数组大小的

4. 虚函数也是类的成员函数,A说法是不正确的;
虚函数和函数重载都实现了C+=的多态性,但表现形式不一样,函数重载调用根据参数个数、参数类型等进行区分,而虚函数则是根据动态联编来确定调用什么。
函数重载可以是类的成员函数也可以是非成员函数,比如:
1
2
int fun( int a);
int fun( int a,  int b);
这就是非成员重载,虚函数必须是成员函数了,否则就失效了。

5. 处理a.html文件时,以下哪行伪代码可能导致内存越界或者抛出异常()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
          int totalBlank =  0 ;
          int blankNum =  0 ;
          int taglen = page.taglst.size();
A        for ( int i =  1 ; i < taglen- 1 ; ++i)
         {
                  //check blank
B              while (page.taglst[i] ==  "<br>" && i < taglen)
                {
C                       ++totalBlank;
D                       ++i;
                }
E              if (totalBlank >  10 )
F                      blankNum += totalBlank;
G             totalBlank =  0 ;
         }
注意:以下代码中taglen是html文件中存在元素的个数,a.html中taglen的值是15,page.taglst[i]取的是a.html中的元素,例如page.taglst[1]的值是<html>

答案为B,因为while(page.taglst[i] == "<br>" && i < taglen)这个判断,先执行page.taglst[i] == "<br>"这个判断,如果这个判断返回值为true,再执行i < taglen这个判断。当i=taglen的时候,执行page.taglst[i] == "<br>"这个判断就会越界,所以B处,最先出现越界。

6. 设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?
1
2
3
4
5
6
7
8
C c;
void main()
{
     A*pa= new A();
     B b;
     static D d;
     delete pa;
}

构造函数调用顺序:CDAB
析构函数调用顺序:ABDC
这道题主要考察的知识点是 :全局变量,静态局部变量,局部变量空间的堆分配和栈分配

其中全局变量和静态局部变量时从 静态存储区中划分的空间,
二者的区别在于作用域的不同,全局变量作用域大于静态局部变量(只用于声明它的函数中),
而之所以是先释放 D 在释放 C的原因是, 程序中首先调用的是 C的构造函数,然后调用的是 D 的构造函数,析构函数的调用与构造函数的调用顺序刚好相反。

局部变量A 是通过 new 从系统的堆空间中分配的,程序运行结束之后,系统是不会自动回收分配给它的空间的,需要程序员手动调用 delete 来释放。

局部变量 B 对象的空间来自于系统的栈空间,在该方法执行结束就会由系统自动通过调用析构方法将其空间释放。

之所以是 先 A  后 B 是因为,B 是在函数执行到 结尾 "}" 的时候才调用析构函数, 而语句 delete a ; 位于函数结尾 "}" 之前。

7. 若char是一字节,int是4字节,指针类型是4字节,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
class CTest
{
     public :
         CTest():m_chData(‘\0’),m_nData(0)
         {
         }
         virtual void mem_fun(){}
     private :
         char m_chData;
         int m_nData;
         static char s_chData;
};
char CTest::s_chData=’\0’;
问:
(1)若按4字节对齐sizeof(CTest)的值是多少?
(2)若按1字节对齐sizeof(CTest)的值是多少?

(1) 12=1(char)+3(对齐)+4(int)+4(虚函数表)
(2) 9=1(char)+3(对齐)+4(int)

在类中,如果什么都没有,则类占用1个字节,一旦类中有其他的占用空间成员,则这1个字节就不在计算之内,如一个类只有一个int则占用4字节而不是5字节。

如果只有成员函数,则还是只占用1个字节,因为类函数不占用空间

虚函数因为存在一个虚函数表,需要4个字节,数据成员对象如果为指针则为4字节,注意有字节对齐,如果为13字节,则进位到16字节空间。


8.

方法重载(overload):
1.必须是同一个类
2方法名(也可以叫函数)一样
3参数类型不一样或参数数量不一样

方法的重写(override)两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。



9.输出数组的全排列:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void  perm( int  list[],  int  k,  int  m)
{
     if  (k == m)
     {
         copy(list, list + m, ostream_iterator< int >(cout,  " " ));
         cout << endl;
         return ;
     }
 
     for  ( int  i = k; i<m; i++)
     {
         swap(list[k], list[i]);
         perm(list, k + 1, m);
         swap(list[k], list[i]);
     }
}
 
void  main( void )
{
     int  arr[] = { 1,2,3 };
     perm(arr, 0, 3);
 
     system ( "pause" );
}
   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//参数为引用,函数调用多,所以定义为内联函数
inline  void  charSwap( char  &_left,  char  &_right)
{ // 交换_left和_right 
     char  temp = _left;
     _left = _right;
     _right = temp;
}
//arr为字符数组,nPrefix表示前缀的下标,nSize表示arr大小(字符个数)
void  fullPermulation( char  arr[],  int  nPrefix,  int  nSize)
{ //打印arr[]的全排列 
     int  i = 0;
     if  (nPrefix == nSize - 1)
     { //前缀是最后的位置,打印一个排列 
         for  (i = 0; i<nSize; i++)
             putchar (arr[i]);
         putchar ( '\n' );
     }
     else
     { //arr[nPrefix...nSize-1]有多种排列方式,递归地产生这些排列方式 
         for  (i = nPrefix; i<nSize; i++)
         {
             if  (i != nPrefix)
                 charSwap(arr[nPrefix], arr[i]); //交换前缀,产生下一次前缀
             fullPermulation(arr, nPrefix + 1, nSize);
             if  (i != nPrefix)
                 charSwap(arr[nPrefix], arr[i]); //恢复原有的顺序
         }
     }
}
int  main()
{
     char  arr[] = {  '1' '2' '3'  };
     fullPermulation(arr, 0,  sizeof (arr) /  sizeof ( char ));
     system ( "pause" );
     return  0;
}


10.static 修饰局部变量:1)只有第一次进入函数时初始化
                                       2)生命期在离开main函数时结束
                                       3)存储在全局区
                                       4)不重新初始化


11.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<iostream>
using namespace std;
class MyClass
{
public :
     MyClass( int i =  0 )
     {
         cout << i;
     }
     MyClass( const MyClass &x)
     {
         cout <<  2 ;
     }
     MyClass &operator=( const MyClass &x)
     {
         cout <<  3 ;
         return * this ;
     }
     ~MyClass()
     {
         cout <<  4 ;
     }
};
int main()
{
     MyClass obj1( 1 ), obj2( 2 );
     MyClass obj3 = obj1;
     return 0 ;
}
运行时的输出结果是()

122444 

C MyClass obj3 = obj1;
obj3还不存在,所以调用拷贝构造函数输出 2
如果obj3存在,obj3=obj,则调用复制运算符重载函数,输出 3


12. 如下代码输出结果是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
char *myString()
{
     char buffer[ 6 ] = { 0 };
     char *s =  "Hello World!" ;
     for ( int i =  0 ; i < sizeof(buffer) -  1 ; i++)
     {
         buffer[i] = *(s + i);
     }
     return buffer;
}
int main( int argc,  char **argv)
{
     printf( "%s\n" , myString());
     return 0 ;
}

字符数组是在栈区分配的,函数返回后就被回收了,所以指针指向的值未知。这是将字符数组赋值写在非main函数中设置的陷阱。
当函数返回值之后,其函数内部的栈空间均会被销毁;
在函数内部,若程序员没有为指针分配空间,则函数退出时,其栈空间也就不存在了;
因此,使用数组时,不能返回一个数组;
但是 上述代码在VS2015环境中输出为Hello.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值