您的位置:首页 > 编程语言 > C语言/C++

2016_2_28 c++能力评估20题

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

x1,

x2,

x3=
10
,

x4,

x5,

}x;
函数外部问x等于什么?5
12
0
随机值enum只是定义了一个常量集合,里面没有“元素”,枚举类型是当做int类型存储的,sizeof值都为4,并且系统为其初始化为0;但是在vs2015中,sizeof值的确是4,但输出x报错:使用了未初始化的局部变量“x”3.
123456789101112
void
example(
char
acWelcome[]){

printf
(
"%d\n"
,
sizeof
(acWelcome));

return
;

}

void
main(){

char
acWelcome[]=
"WelcometoHuaweiTest"
;

example(acWelcome);

cout<<
sizeof
(acWelcome)<<
""
<<
strlen
(acWelcome)<<endl;

system
(
"pause"
);

return
;

}
输出结果:42322
32位系统是464位系统是8,数组作为函数的参数是会退化为函数指针的,想想看,数组作为函数参数的时候经常是需要传递数组大小的4.虚函数也是类的成员函数,A说法是不正确的;虚函数和函数重载都实现了C+=的多态性,但表现形式不一样,函数重载调用根据参数个数、参数类型等进行区分,而虚函数则是根据动态联编来确定调用什么。函数重载可以是类的成员函数也可以是非成员函数,比如:
12
int
fun(
int
a);

int
fun(
int
a,
int
b);
这就是非成员重载,虚函数必须是成员函数了,否则就失效了。5.处理a.html文件时,以下哪行伪代码可能导致内存越界或者抛出异常()
123456789101112131415
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
)

FblankNum+=totalBlank;

GtotalBlank=
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析构函数调用顺序为?
12345678
Cc;

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是在函数执行到结尾"}"的时候才调用析构函数,而语句deletea;位于函数结尾"}"之前。7.若char是一字节,int是4字节,指针类型是4字节,代码如下:
12345678910111213
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.输出数组的全排列:
12345678910111213141516171819202122232425
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"
);

}

123456789101112131415161718192021222324252627282930313233343536
//参数为引用,函数调用多,所以定义为内联函数

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.
1234567891011121314151617181920212223242526272829
#include<iostream>

usingnamespacestd;

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
CMyClassobj3=obj1;
obj3还不存在,所以调用拷贝构造函数输出
2
如果obj3存在,obj3=obj,则调用复制运算符重载函数,输出
3
12.如下代码输出结果是什么?
12345678910111213141516
#include<stdio.h>

char
*myString()

{

char
buffer[
6
]
={
0
};

char
*s
=
"HelloWorld!"
;

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: