目录
错题1
32位机器上,以下代码的输出是()
char c = -1;
int i0 = c;
int i1 = (unsigned char)c;
printf("%d, %d\n", i0, i1);
答案 -1,255
解析:
[unsigned]char 到 [unsigned]int需要类型提升
类型提升时,有符号型高位补符号位,无符号型高位补0(是对这个数的补码补码补码进行补位!)
char c = -1,所以它的原码是1000 0001,补码是1111 1111
先看i0,是 char->int 的转换,有符号型提升,于是高位补符号位,所以i0的补码就是1111 1111 1111 1111,所以换回原码i0 = -1
再看i1,是先(1)char->unsigned,再(2)unsigned char->int 的转换:
(1)这一步不涉及补位,也就是说数字的补码不变,还是1111 1111,但是这时候已经没有符号位了,变成了无符号型
(2)无符号型提升,高位补0,所以i1的补码就是0000 0000 1111 1111
所以换回原码i1 = 255
错题2
下述有关虚函数和纯虚函数说法错误的是()
A. 被virtual关键字修饰的成员函数,就是虚函数 |
---|
B. 在基类中实现纯虚函数的方法是在函数原型后加"=0",virtual void funtion1()=0 |
C. 同时含有纯虚拟函数的类称为抽象类,它可以被实例化,但是对象不可以调用纯虚函数 |
D. 使用纯虚函数的意义是在很多情况下,基类本身生成对象是不合情理的 |
答案 C
解析:抽象类不能被实例化,因为它的纯虚函数都没实现,如果通过实例调用纯虚函数就会出错。
2022.12.02
错题3
下面函数的时间复杂度是()
long foo(long x){
if(x < 2) return 1;
return x * x * foo(x - 1);
}
答案 O(N)。
解析:程序递归了N-1次
错题4
seekp和seekg的区别和记忆点
1.seek 是寻找 寻求的意思
2.tell 是告诉 告知的意思
3.那 p 即put 放和输出的意思,在这里是保存到文件
4.那 g 即get 是获取,读入的意思,在这里是从文件读取
所以
1.seekp 可用于将信息 put(放入 写入)到文件中
2.seekg 则可用于从文件中 get(获取)信息。
3.tellg()函数不需要带参数,它返回当前定位指针的位置,也代表着输入流的大小。
错题5
定义char dog[]=“wang\0miao”;那么sizeof(dog)与strlen(dog)分别是多少:
答案 10,4
解析:字符数组结尾有隐式’\0’结束符,所以sizeof(dog)为10;
‘\0’为结束符,每个字符串后都有’\0’,在编译器读到这里时默认字符串结束,所以strlen(dog)为4.
错题6
在下列选项中,用于清除基数格式位设置以十六进制数输出的语句是( )
A.cout << setf(ios::dec, ios::basefield); |
---|
B.cout << setf(ios::hex, ios::basefield); |
C.cout << setf(ios::oct, ios::basefield); |
D.cin >> setf(ios::hex, ios::basefield); |
答案 B
解析:
cout 的 setf 表示设置输出基数格式,D 选项错误。
ios::dec 表示 10 进制,A 选项错误。
ios::oct 表示 8 进制,C 选项错误。
ios::hex 表示 16 进制,B 选项正确。
错题7
关于子类型的描述中,( )是错误的?
A.在公有继承下,派生类是基类的子类型 |
---|
B. 子类型关系是不可逆的 |
C. 子类型就是指派生类是基类的子类型 |
D. 一种类型当它至少提供了另一种类型的行为,则这种类型是另一种类型的子类型 |
答案 C
解析 子类和子类型不一样,后者表示可以表示父类一些一样的行为就可以称为子类型,不可逆,私有继承的子类不是子类型。
2022.12.04
错题8
下列哪一个循环会导致死循环?()
A. for(int k=0;k<0;k++) |
---|
B. for(int k=10;k>0;k–) |
C. for(int k=0;k<10;k–) |
D. 没有答案 |
答案 D
解析:
A 选项,循环一次不会执行。k = 0,判断 k < 0,不满足直接结束循环。
B 选项,当 k 不断减小到 0 时,条件不满足结束循环。
C 选项,k 为 int,不断递减后,最小值可为 -2147483648,再递减其值会溢出变为2147483647,结束循环。
错题8
在上下文及头文件均正常的情况下,若有以下定义和语句,则输出结果为:
char s1[] = "12345", *s2 = "1234";
printf("%d\n", strlen(strcpy(s1, s2)));
答案 4
解析:strlen只输出不包含结尾‘\0’的长度,sizeof加数组则会输出包括‘\0’长度的大小。
错题9
请指出以下程序的错误:
void GetMemory(char **p, int num){
if(NULL == p && num <= 0)//1
return;
*p = (char*)malloc(num);
return;
}
void main(void){
char *str = NULL;
GetMemory(&str, 80); //2
if(NULL != str){
strcpy(&str, "hello"); //3
printf(str);
}
return true; //4
}
答案 134
解析:
对于1:可能要写成*p?或者&&改为||?
对于3:应该是strcpy(str, “hello”);
对于4:main的返回类型是void。
2022.12.07
错题10
以下字符中不是转义字符的是( )
A.‘\a’ |
---|
B.‘\b’ |
C.‘\c’ |
D.‘\\’ |
答案 C
解析:
A 选项 ‘\a’ 表示响铃(BEL)
B 选项 ‘\b’ 表示退格(BS) ,将当前位置移到前一列
C 选项不是转义字符
D 选项 ‘\’ 表示反斜杠
完整的转义字符及含义如下:
\a 响铃(BEL)
\b 退格(BS)
\f 换页(FF),将当前位置移到下页开头
\n 换行(LF) ,将当前位置移到下一行开头
\r 回车(CR) ,将当前位置移到本行开头
\t 水平制表(HT)
\v 垂直制表(VT)
’ 单引号
" 双引号
\ 反斜杠
2022.12.08
错题11
请问在 64 位平台机器下 sizeof(string_a),sizeof(string_b) 大小分别是()
char *string_a = (char *)malloc(100*sizeof(char));
char string_b[100];
答案 8 100
解析:
string_a是一个char型的指针,在64位系统中sizeof(char*)=8
string_b是一个char型的数组,在64位系统中sizeof(char)=1,共100值因此为100
错题12
以32位C++程序,请计算sizeof的值______
void Func ( char str[100] ) { sizeof( str ) = ? }
void*p = malloc( 100 ); sizeof( p ) = ?;
答案 4 4
数组做函数参数,会退化成指针,所以为4字节,p为指针,也为4字节。
错题13
下列程序的运行结果是 YY,78,96,请为横线处选择合适的程序( )
#include <stdio.h>
#include <string.h>
typedef struct {
char name[9];
float score[2];
} STU;
void f(STU _______) {
STU b = {"YY", 78, 96};
int i;
strcpy(a->name, b.name);
for (i = 0; i < 2; i++)
a->score[i] = b.score[i];
}
main() {
STU c = {"LL", 90, 80};
f(&c);
printf("%s,%.0f,%.0f\n", c.name, c.score[0], c.score[1]);
}
*A.a |
---|
B.a |
C.&a |
D.a[] |
答案 A D
解析:数组作为参数传递会退化为指针,所以AD等价
2022.12.09
错题14
以下程序的输出结果是()
#include <stdio.h>
void fun(char **p) {
int i;
for (i = 0; i < 4; i++)
printf("%s", p[i]);
}
main() {
char *s[6] = {"ABCD", "EFGH", "IJKL", "MNOP", "QRST", "UVWX"};
fun(s);
printf("\n");
}
答案 ABCDEFGHIJKLMNOP
解析:本题考查字符串数组,s表示指向字符数组的指针,s指向了第一个字符串,s + +指向了第二个字符串,所以最后输出结果为D选项。
错题15
下面有关回调函数的说法,错误的是?
A.下面有关回调函数的说法,错误的是? |
---|
B.回调函数可能被系统API调用一次,也可能被循环调用多次 |
C.回调函数本身可以直接是全局函数 、静态函数或某个特定类的成员函数 |
D.回调函数可用于通知机制 |
答案 C
解析:
考察点:this指针
核心就是类成员函数需要this指针访问函数,而全局或者静态函数不需要this指针。
简言之,类的成员函数需要隐含的this指针 而回调函数没有办法提供。
基础概念:
回调函数就是一个通过函数指针调用的函数。
如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
参考讨论:
http://bbs.csdn.net/topics/380257801
http://baike.baidu.com/view/414773.htm
2022.12.10
错题16
若MyClass是一个类名,其有如下语句序列,下面的语句序列调用构造函数个数是( )
MyClass c1,*c2;
MyClass *c3=new MyClass;
MyClass &c4=c1;
答案 2
解析:
只要类的对象被创建,就会执行构造函数。
第1行:创建对象c1,调用了构造函数;
第2行:声明了一个指向MyClass类型的指针,未调用构造函数;
第3行:new MyClass在内存中创建了一个对象,并把对象地址赋给指针c3,创建对象调用了构造函数;
第4行:将c4声明为引用,并将c1赋给它,即c4只是c1的一个引用,未调用构造函数。
错题17
在32位环境下,以下代码输出的是()
#include<stdio.h>
class A {
public:
A(){ printf("A");}
~A(){ printf("~A");}
};
class B : public A {
public:
B(){ printf("B");}
~B(){ printf("~B");}
};
int main() {
A *c = new B[2];
delete[] c;
return 0;
}
答案 ABABAA
解析:
#include<stdio.h>
class A
{
public:
A(){ printf(“A”);}
~A(){ printf(“~A”);
}; // 基类A 析构函数不是虚函数
class B:public A
{
public;
B(){ printf(“B”);}
~B(){ printf(“~B”);}
};//派生类 B
int main()
{
A*c = new B[2]; //定义了一个 A类的对象指针 ,只不过用派生类B来替代 也就是派生类动态分配的内存
//初始化从基类开始,然后是派生类 ABAB
delete[] c;// 释放内存,通过的是 基类指针,调用的是基类的析构函数,那么派生类对象中的动态内存分配的空间没有释放,造成了内训泄露
//派生类对象的内存 在对象消失后,既不能被本程序使用,也没有被释放。
//对于内存需求量大,长期连续运行的内存来说,如果持续发生这样的错误是很危险的,最终导致内存不足引起程序的终止
return 0;
}
2022.12.11
错题18
下面代码段执行后输出结果是()
int i = 1, j = 1, k = 2;
if ((j++ || k++) && i++)
printf("%d,%d,%d\n", i, j, k);
答案 222
解析:
||或逻辑:左边为真,就会忽略右边表达式
&&与逻辑:左边为假,就会忽略右边表达式
错题19
print函数声明为void print(int a,char b=‘b’,int c=1); 下面函数调用正确的是()
A.print(‘a’); |
---|
B.print(5,8); |
C.print(5,‘#’); |
D.print(5,‘#’,2); |
答案 ABCD
解析:CD毫无疑问是对的,A的话字符转为整数即为97,B整数赋值为char,为截断赋值 把整数的前3*8位去掉 直接后8位赋值给char。
错题20
对于下面的代码段,则能完成i=j赋值功能的语句是( )
int i, j = 2, *p = &i;
*A.i=p; |
---|
B.*p=*&j; |
C.i=&j; |
*D.i=*p; |
答案 B
解析:*&j表示对j的地址解引用则为j的值,*p指向i。
2022.12.12
错题21
若有以下说明和定义,在必要的赋值之后,对fun函数的正确调用语句是()
int fun (int *c) { … }
int main(){
int (*a)(int*)=fun,*b(),w[10],c;
…
}
A.a=a(w); |
---|
B.(*a)(&c); |
C.b=*b(w); |
D.fun(b); |
答案 B
解析:
a为函数指针 接受一个int*型变量返回一个int型变量 所以选项A的返回值类型不对
a(&c)与(*a)(&c)在调用上是等价的 都等于fun(&c) B正确
int *b();这个很具有疑惑性 它并不是函数指针,而是一个返回值为int*型,无输入参数,而且名为b的函数申明。显然C错误,函数指针要这么写int (*b)();
fun函数必须接受int*型的参数 D显然错误
错题22
如下代码的输出结果是()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnJHD6b0-1679561059620)(2022年12月.assets/image-20221212094703029.png)]
答案 9
解析:
数组名是数组这种类型的变量名,所以对数组名取地址是取的整个数组的地址,所以&a+1自然要跨过整个数组的长度,本题即跨过2*5 = 10个int的长度。
有了上述概念,再来分析这道题,int *ptr = (int *)(&a+1),p此时指向的地址应该是a[1] [4]后面的地址,由于ptr是int型指针,ptr-3应该是ptr向前移动3个元素,即ptr-3指向a[1] [2],所以*(ptr -3) = 9
1、&a+1跨整个变量(二维数组)。
2、a+1跨一维数组。
3、a[0]+1跨一个int。
错题23
在下列表示引用的方法中,( )是正确的。
已知:int m=10;
A.int &x=m; |
---|
B.int &y=10; |
C.int &z; |
D.float &t=&m; |
答案 A
解析:B不能指向常量,C必须初始化,D&m返回值为int*
错题24
void (*f)(int *, int *);
下列说法正确的是()
A.定义了函数的指针f,f所指函数返回指针 |
---|
B.声明了一个返回值为指针的函数f |
C.声明了一个无返回值的函数f |
D.定义了函数的指针f,f所指函数无返回值 |
错题25
以下程序输出结果是____。
class A
{
public:
virtual void func(int val = 1)
{ std::cout<<"A->"<<val <<std::endl;}
virtual void test()
{ func();}
};
class B : public A
{
public:
void func(int val=0)
{std::cout<<"B->"<<val <<std::endl;}
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();
return 0;
}
答案 B->1
解析:
记住:virtual 函数是动态绑定,而缺省参数值却是静态绑定。 意思是你可能会 在“调用一个定义于派生类内的virtual函数”的同时,却使用基类为它所指定的缺省参数值。
结论:绝不重新定义继承而来的缺省参数值!(可参考《Effective C++》条款37)
B*p = newB;` `p->test();
p->test()执行过程理解:
(1) 由于B类中没有覆盖(重写)基类中的虚函数test(),因此会调用基类A中的test();
(2) A中test()函数中继续调用虚函数 fun(),因为虚函数执行动态绑定,p此时的动态类型(即目前所指对象的类型)为B*,因此此时调用虚函数fun()时,执行的是B类中的fun();所以先输出“B->”;
(3) 缺省参数值是静态绑定,即此时val的值使用的是基类A中的缺省参数值,其值在编译阶段已经绑定,值为1,所以输出“1”;
最终输出“B->1”。所以大家还是记住上述结论:绝不重新定义继承而来的缺省参数值!
错题26
常量指针和指针常量记忆如果*号出现在const右边则代表数值不可改变,*号出现在const左边代表指针指向不可改变!!!!
如 int const * a=10,const int * a=10为常量指针则(*a)不可改变
反之int * const a=10,则为指针常量,a不可改变。
2022.12.13
错题27
What’s the output of below code on a 64-bit system?
#include <iostream>
using namespace std;
struct data {
int type;
struct {
unsigned int a:1;
unsigned int b:1;
unsigned int c:4;
unsigned int d:4;
unsigned int e:4;
unsigned int f:4;
unsigned int g:4;
unsigned int h:8;
unsigned int i:8;
} flags;
struct {
unsigned int a:1;
unsigned int b:1;
} flagsEx;
};
int main() {
data temp;
int a = sizeof(data);
int b = sizeof(temp);
data *pTemp = new data();
int c = sizeof(pTemp);
delete pTemp;
pTemp = NULL;
cout << a << ", " << b << ", " << c << endl;
return 0;
}
答案 16 16 8
解析 :
int type类型占4个字节
flags占1+1+4+4+4+4+4+8+8=38bit,由于一个unsigned int占4个字节32bit,38>32,内存对齐后为8个字节。
flagsEX占1+1=2bit,内存对齐后为4字节(unsigned int所占字节数)
所以 a:4+8+4=16;
b=a=16;
c为指针,在64位系统中指针占8个字节,所以c=8;
错题28
派生类对象可以访问基类成员中的()?
A.公有继承的私有成员 |
---|
B.私有继承的公有成员 |
C.公有继承的保护成员 |
D.以上都错 |
答案 D
解析:
public 公共权限 类内可以访问 类外可以访问
protected 保护权限 类内可以访问 类外不可以访问
private 私有继承 类内可以访问 类外不可以访问
当继承时
2022.12.26
错题29
声明语句为int a[3] [4]; 下列表达式中与数组元素a[2] [1]等价的是:
A.*(a[2]+1) |
---|
B.a[9] |
C.*(a[1]+2) |
D.*(*(a+2))+1 |
答案 A
解析>a[i] [j] =*(a[i]+j) = *(*(a+i)+j) =(*(a+i))[j]
对于二维数组,本身存在两个星号,a代表数组开始地址,*(a+0)表示第0行起始地址,此时与a相同,若*(a+1)则代表第1行的起始地址,此时再加*号则代表解引用,若后边加上j则代表此行的第几个数据,如*(*(a+1)+j)代表第一行的第j个数。不加外边的*则表示地址。
int main() {
int a[3][5];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
a[i][j] = i * 10 + j;
}
}
cout << a << endl;
cout << *(a+1) << endl;
cout << *( * (a + 1)) << endl;
return 0;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-klXBPU69-1679561059621)(2022年12月.assets/image-20221227102733558.png)]
错题30
以下程序输出结果是____
#include <iostream>
using namespace std;
class A{
public:
A ():m_iVal(0){test();}
virtual void func() { std::cout<<m_iVal<<' ';}
void test(){func();}
public:
int m_iVal;
};
class B : public A{
public:
B(){test();}
virtual void func(){
++m_iVal;
std::cout << m_iVal << ' ';
}
};
int main(int argc ,char* argv[]){
A*p = new B;
p->test();
return 0;
}
答案 012
解析
A*p = new B; // 1、先调用A的构造函数,此时m_ival通过初始化列表初始为0,同时构造函数掉用test(),test()调用A::func(), 因为现在还没有B出现,所以输出 0。2、调用B的构造函数,函数调用从A类继承过来的A::test(),然后test()调用B::func(),因为func()是虚函数,所以输出 1.
p->test(); // 3、这里开始根据p的A类的指针,并且test是普通函数,所以调用A::func(), 但是func()的虚函数特性,所以调用B::func(), 输出 3.
2022.12.27
错题31
以下程序运行后的输出结果是()
int main() {
int a=1,b=2,m=0,n=0,k;
k=(n=b<a)&&(m=a) ;
printf("%d,%d\n",k,m);
return 0;
}
答案 0 0
解析 :n=b<a为0则m=a不执行,&&为惰性运算符
错题32
若有定义如下,定义中a的类型与下面选项中完全相同的是?
A.char a[10] ; |
---|
B.char (*a)[10] ; |
C.char * a ; |
D.char *a[10] ; |
答案 B
解析
理清楚数组符号[]和谁搭配,就容易搞懂这些问题了。
比如char a[10],char和[10]搭配,意思是10个字符长的字符数组,a就是一个这样的字符数组。
那么char *a[10]呢?char*是字符指针,char*和[10]搭在一起,意思是10个字符指针长的字符指针数组,a就是这样一个字符指针数组。
而char(*a)[10]呢?因为有括号,*是和a结合在一起,而char是和[10]在一起,则是10个字符长的字符数组,*a是这样的一个字符数组,也就是说a是指向这样一个字符数组的指针。
typedef char T[10]呢?char和[10]搭在一起,意思是10个字符长的一个数组,typedef定义了T是char[10]这样的一种数据类型。
T * a;*应该和a搭在一起,所以a就是指向T这样一种数据类型的指针,所以等价于char (*a)[10]
2022.12.28
错题33
以下程序的输出结果为()
using namespace std;
void print(char **str) {
++str;
cout<<*str<<endl;
}
int main() {
static char *arr[]={"hello", "world", "c++"};
char **ptr;
ptr=arr;
print(ptr);
return 0;
}
答案 world
解析
可以把 *ptr当作一个整体,指向一个char* 的字符串,然后注意下面这些情况:
*ptr = arr[0] = "hello"
(*ptr)[1] = arr[0][1] = 'e'
(*ptr + 1) = arr[0][1:] = "ello"
*(ptr + 1) = arr[1] = "world"
错题34
c/c++中,有关纯虚函数说法正确的是( )
A.子类中必须覆盖基类的纯虚函数 |
---|
B.含有纯虚函数的类不能被实例化 |
C.子类中必须覆盖基类的虚函数 |
D.含有纯虚函数的类一定是抽象类 |
答案 B D
含有纯虚函数的类是抽象类,继承这个抽象类的子类可以覆盖也可以不覆盖纯虚函数。如果基类中的纯虚函数在子类中没有覆盖,那这个子类还是一个抽象类,不能实例化
错题35
一、什么是内联函数?
内联函数是在 C++ 中增加的一个功能,可以提高程序执行效率。如果函数是内联的,编译器在编译时,会把内联函数的实现替换到每个调用内联函数的地方,可以与宏函数作类比,但宏函数不会进行类型检查。
可以将普通函数或者类的成员函数声明为内联。
内联函数一般要求如下:
-
函数简短,通常3-5行;
-
函数内没有复杂的实现,比如:包含while、for 循环,递归等;
-
通常在多处有调用;
注意:函数声明为内联,仅仅是对编译器的建议,如果函数比较复杂,编译器会将其看做普通函数。
二、为什么要使用内联函数 ?
引入内联函数主要是解决一些频繁调用的小函数消耗大量空间的问题。
通常情况下,在调用函数时,程序会将控制权从调用程序处转移到被调用函数处,在这个过程中,传递参数、寄存器操作、返回值等会消耗额外的时间和内存,如果调用的函数代码量很少,也许转移到调用函数的时间比函数执行的时间更长。而如果使用内联函数,内联函数会在调用处将代码展开,从而节省了调用函数的开销。
三、哪些函数不能是内联函数?
-
递归调用本身的函数;
-
包含复杂语句的函数,例如:for、while、switch 等;
-
函数包含静态变量;
四、使用内联函数的缺点
1.如果使用很多内联函数,生成的二进制文件会变大;
2.编译的时间会增加,因为每次内联函数有修改,就需要重新编译代码。
所以,并不是所有函数都要声明为内联函数,需要视具体情况而定。
五、总结
内联函数能够减少函数调用的开销,但是,应该在符合一定内联函数的情况下使用。
错题36
c++语言中,类ClassA的构造函数和析构函数的执行次数分别为()
ClassA *pclassa=new ClassA[5];
delete pclassa;
答案 5,1
解析
很明显构造函数调用了5次,这边考察delete和delete[] 的区别。delete和delete[]都能释放指针所指向的内存区域。但delete只会调用一次析构函数,而delete[]还会调用后续所有对象的析构函数。当数据类型为基本数据类型时,用delete和delete[]都可以,因为基本数据类型没有析构函数。
2022.12.29
错题37
设x为整型变量,不能正确表达数学关系1<x<5的C++逻辑表达式是()
A.1< x <5 |
---|
B.x2||x3||x==4 |
C.1<x && x<5 |
D.! (x<=1)&&! (x>=5) |
答案 A
错题38
调用recv(int sockfd, void *buf, size_t len, int flags)的过程中,一共进行了几次内存复制操作?
答案 2
解析:
1.首先知道网卡接收数据,(计算机结构我就省略了,说不完),网卡收到网线传来的数据之后,经过硬件电路传输,会将数据写入内存的某个地址上。(这之间会涉及DMA、IO通路选择等知识)。这一步不重要,需要知道网卡会把数据写入内存即可。(理解为内核缓冲区)
2.网卡向CPU发出中断信号,通知系统有新数据到来。CPU执行中断程序,将之前写入内存的数据写入对应的socket的接收缓冲区里。
3.唤醒阻塞在recv上的进程,recv将socket的接收缓冲区内数据拷贝到用户定义的缓冲区buf中。
在内存上的复制操作应该是指:内核缓冲区->socket接收缓冲区->用户定义的buf缓冲区。
错题39
关于下列操作复杂度为O(1)的是()
A.vector中插入元素(动态数组) |
---|
B.set中查找元素 |
C.hash_map中查找元素 |
D.deque尾部删除元素 |
答案 CD
解析:
vector插入 ,该位置插入后后面的都要改变O(n)
Set底层红黑树 O(logn)
Hash_map 底层哈希表 O(1)
Deque尾部可以直接修改O(1) Deque为双端队列,queue为队列
2022.12.30
错题40
下面程序输出的是:
#define f(x) x*x
main (){
int a=5,b=2,c;
c=f(a)/f(b);
printf("%d",c);
}
答案 24
int 会有精度损失,12.5变为12
错题41
以下涉及到内存管理的代码段中,有错误的是:
A.int *a=new int(12); //… free(a); |
---|
B.int *ip=static_cast<int*>(malloc(sizeof(int))); *ip=10; //… delete ip; |
C.double *a=new double[1]; //… delete a; |
D.int *ip=new int(12); for(int i=0;i<12;++i){ ip[i]=i; } delete []ip; |
答案 ABD
解析:
new和delete搭配,malloc和free搭配,所以A、B是错的。 关于D,注意new int(12)和new int[12]的区别。new int(12)是生成了一个值为12的int变量,new int[12]才是生成一个大小为12的数组。所以,delete []ip是错误的,D错。 再看C,乍一眼看过去,a是一个数组,应该用delete []a,但是在基本类型数组来说,delete a和delete []a的效果是一样的。如果,a是一个自定义对象的数组,那么只能用delete []a。
错题42
若有以下类W说明,则函数fConst的正确定义是( )。
class W
{
int a;
public:
void fConst(int&) const;
};
A.void W::fConst( int &k )const { k = a; } |
---|
B.void W::fConst( int &k )const { k = a++; } |
C.void W::fConst( int &k )const { cin >> a; } |
D.void W::fConst( int &k )const { a = k; } |
答案 A
解析:
“编译器会自动给每一个函数加一个this指针。在一个类的函数后面加上const后,就表明这个函数是不能改变类的成员变量的(加了mutable修饰的除外)。实际上,也就是对这个this指针加上了const修饰”。
2022.12.31
错题43
以下对一维数组a的定义正确的是()
A.int n = 5, a[n]; |
---|
B.int a(5); |
C.const int N = 5; int a[N]; |
D.int n; cin>>n; int a[n]; |
答案 C
解析:数组中括号里必须是常量
错题44
假设Aclass为抽象类,下列正确的语句是()
A.Aclass fun( int ); |
---|
B.Aclass *p; |
C.int fun( Aclass ); |
D.Aclass Obj; |
答案 B
解析
抽象类的规定
(1)抽象类只能用作其他类的基类,不能建立抽象类对象。//D
(2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。// A C
(3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。// B
错题45
下列代码的运行结果()
short i = 65537;
int j = i + 1;
printf("i=%d,j=%d\n", i, j);
答案 1,2
解析:
首先说明,short类型的表示范围是 -32768 ~ + 32767,说最大可以表示65535的人是不是认为了unsigned short(无符号)?
65537用int表示,为0000 0000 0000 0001 0000 0000 0000 0001,转化为short的时候高两位字节丢失,于是变成1
求j的值是再将i转化为int类型,高位两位字节补0,所以i没有变化,j的值为2。
错题46
下面有关C++的类和C里面的struct的描述,正确的有?
A.在C++中,来自class的继承默认按照private继承处理,来自struct的继承默认按照public继承处理 |
---|
B.class的成员默认是private权限,struct默认是public权限 |
C.c里面的struct只是变量的聚合体,struct不能有函数 |
D.c++的struct可有构造和析构函数 |
答案 ABCD
解析 题目说的是C里面的struct,在C中,结构体不能继承,更不用谈有无构造函数和析构函数了。
错题47
math.h的abs返回值()
A.不可能是负数 |
---|
B.不可能是正数 |
C.都有可能 |
D.不可能是0 |
答案 C
解析
因为负数的范围比正数大一个,比如8位的二进制,可以表示范围为-128~127,所以abs(-128)可能并不能表示为128
所以只能返回原值。