【C++知识点】知识点

1. malloc在生产自定义类型时,里面的成员变量的空间需要单独处理吗??

struct buffertest {
    char strbuffer1[8];
    char strbuffer2[8];
    char strbuffer3[8];
};

       当你使用malloc来创建一个buffertest类型的结构体时,malloc会分配buffertest所需的空间(即24字节),并返回一个指向该内存区域的指针。

malloc(sizeof(buffertest)) 会为 buffertest 类型的结构体分配 24 字节的内存空间,其中:

  • strbuffer1 会占用前 8 字节。
  • strbuffer2 会占用接下来的 8 字节。
  • strbuffer3 会占用最后的 8 字节。

       虽然结构体本身被分配了内存,但结构体的成员变量(strbuffer1strbuffer2strbuffer3)并不是单独的内存块,而是直接位于结构体分配的内存空间中的。换句话说,malloc 分配了 24 字节的连续内存空间,结构体的成员变量分别占据了这些空间的不同部分。

typedef struct {
    char* name;  // 字符串的指针
    int age;
} Person;

       当你使用 malloc 来分配 Person 类型的内存时,malloc 只会为整个结构体本身分配内存。它并不会为 name 这个指针指向的字符串分配内存空间,而是仅仅为 name 指针本身分配内存空间(即指针变量的内存)。至于 name 所指向的字符串,你需要单独为它分配内存。

2. 下面关于C++缺省函数描述错误的是:CD

A.缺省参数是声明或定义函数时为函数的参数指定一个默认值.

B.在调用有缺省参数的函数时,如果没有指定实参则采用该默认值,否则使用指定的实参

C.C和C++都支持缺省参数

D.全缺省就是参数全部给缺省值,半缺省就是缺省一半的值

C:纯C语言,即.c文件,函数不支持缺省参数,C++即.cpp文件支持

D:半缺省不能随便缺省一半,必须从右往左缺省,否则编译出错 

 3. 指针通过某一个指针变量指向一个对象后,他所指向的变量间接操作。程序中使用指针程序的可读性差,而引用本身就是目标变量别名,对引用的操作就是对目标变量的操作。

4. 关于C++的inline关键字,以下说法正确的是:C

A.使用inline关键字的函数会被编译器在调用处展开

B.头文件中可以包含inline函数的声明

C.可以在同一个项目的不同源文件内定义函数名相同但实现不同的inline函数

D.递归函数也都可以成为inline函数

A.不一定,因为inline只是一种建议,需要看此函数是否能够成为内联函数

B. inline函数不支持声明和定义分离开,因为编译器一旦将一个函数作为内联函数处理,就会在调用位置展开,即该函数是没有地址的,也不能在其他源文件中调用,故一般都是直接在源文件中定义内联函数的

C.inline函数会在调用的地方展开,所以符号表中不会有inline函数的符号名,不存在链接冲突。

D.比较长的函数,递归函数就算定义为inline,也会被编译器忽略,故错误

5. this指针

this指针代表了当前对象,能够区分每一个对象的自身数据。基类公有成员在子类和对象外都可以直接访问,与this无关 。静态成员函数没有this指针,只有非静态成员函数才有,且为隐藏指针。this指针在非静态的成员函数里面,对象不存在。

6. 类的定义

构造函数不能有返回值,包括void类型也不行。 

自动生成的缺省拷贝构造函数,作为该类的公有成员,否则无法进行默认的拷贝构造

7. 构造函数和析构函数 

与++a等效的运算符函数调用形式为:a.operator++()

区分前缀后缀时,后缀运算需要加一个int参数

无参成员函数相当于有一个参数的全局函数,不能是二元运算符

8. 构造函数初始化列表

static const char* d 是静态成员,只能在类外初始化

静态变量也可以是自定义类型的变量

static成员变量在对象生成之前生成

static函数唯一能够访问的就是static变量或者其他static函数

友元函数不具备this指针,更谈不上this调用

9. 下面有关c++内存分配堆栈说法错误的是( D )

A.对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制

B. 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长

C.对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题

D.一般来讲在 32 位系统下,堆内存可以达到4G的空间,但是对于栈来讲,一般都是有一定的空间大小的

A.栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需  要时需要手动释放

B.栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反

C.频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题

10.  

ClassA *pclassa=new ClassA[5];

delete pclassa;

c++语言中,类ClassA的构造函数和析构函数的执行次数分别为( )

A.5,1

B.1,1

C.5,5

D.程序可能崩溃

A.申请对象数组,会调用构造函数5次,delete由于没有使用[],此时只会调用一次析构函数,但往往会引发程序崩溃

B.构造函数会调用5次

C.析构函数此时只会调用1次,要想完整释放数组空间,需要使用[]

D.正确

11. 使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题?( B )

A.会有内存泄露

B.不会有内存泄露,但不建议用

C.编译就会报错,必须使用delete []p

D.编译没问题,运行会直接崩溃

A.对于内置类型,此时delete就相当于free,因此不会造成内存泄漏

B.正确

C.编译不会报错,建议针对数组释放使用delete[],如果是自定义类型,不使用方括号就会运行时错误

D.对于内置类型,程序不会崩溃,但不建议这样使用

12.  下面有关C++中为什么用模板类的原因,描述错误的是? ( C )

A.可用来创建动态增长和减小的数据结构

B.它是类型无关的,因此具有很高的可复用性

C.它运行时检查数据类型,保证了类型安全

D.它是平台无关的,可移植性

A.模板可以具有非类型参数,用于指定大小,可以根据指定的大小创建动态结构

B.模板最重要的一点就是类型无关,提高了代码复用性

C.模板运行时不检查数据类型,也不保证类型安全,相当于类型的宏替换,故错误

D.只要支持模板语法,模板的代码就是可移植的

类模版中的成员函数全是模版函数

模板类是一个家族,编译器的处理会分别进行两次编译,其处理过程跟普通类不一样

13. T是一个数据类型,在vs系列编译器中,debug模式下,关于std::vector::at 和 std::vector::operator[] 描述正确的是( C )

A.at总是做边界检查, operator[] 不做边界检查.

B.at 不做边界检查, operator[] 做边界检查.

C.at和operator[] 都是会做边界检查的

D.以上都不对

注意题目专门强调了vs系列编译器,debug模式下

at() 和 operator[] 都是根据下标获取任意位置元素的,在debug模式下两者都会去做边界检查。

当发生越界行为时,at 是抛异常,operator[] 内部的assert会触发

故选择C

 14 迭代器

vector的插入操作如果导致底层空间重新开辟,则迭代器就会失效。如果空间足够,不扩容时,迭代器不一定失效,比如push_back尾插,元素插入到空间末尾,在不扩容时不会对迭代器产生影响

vector的删除操作不光会导致指向被删除元素的迭代器失效,删除元素后面的迭代器也会失效 

15 STL中的priority_queue使用的底层数据结构是什么( ):优先级队列priority_queue底层采用vector容器作为底层数据结构

16. 下面关于访问权限与继承权限说法不正确的是( )

A.访问权限和继承权限是不同的概念

B.访问权限和继承权限关键字上是一样的,但是出现位置不一样

C.如果是protected继承方式,基类public的成员变量能通过基类对象在类外直接访问

D.基类私有的成员变量在子类中都不能直接访问,因为没有被子类继承了

A.两个权限控制的东西不一样

B.访问权限在类内部,继承权限在类外

C.只要是public成员对象都可以直接访问

D.基类私有成员不能直接访问不是没有被继承,而是权限问题

下面代码输出结果:( )
class A
{
public:
  void f(){ cout<<"A::f()"<<endl; }
  int a;   
};

class B : public A
{
public:
  void f(int a){cout<<"B::f()"<<endl;}
  int a;
};

int main()
{
  B b;
  b.f();
  return 0;
}

 不能通过编译是正确的,不过原因不是因为成员变量a的问题,而是子类同名隐藏了父类方法的原因

 17. 关于基类与派生类对象模型说法正确的是()

A.基类对象中包含了所有基类的成员变量

B.子类对象中不仅包含了所有基类成员变量,也包含了所有子类成员变量

C.子类对象中没有包含基类的私有成员

D.基类的静态成员可以不包含在子类对象中

E.以上说法都不对

A.静态变量就不被包含

B.同理,静态变量就不被包含

C.父类所有成员都要被继承,因此包含了

D.静态成员一定是不被包含在对象中的

E.很显然,以上说法都不正确

18.  下列说法正确的是()

A.set中的某个元素值不能被直接修改

B.map和unordered_map都是C++11提供的关联式容器

C.因为map和set的底层数据结构相同,因此在实现时set底层实际存储的是<key, key>的键值对

D.map和multimap中都重载了[]运算符

 A:正确,因为set要保证其有序,因此set中元素不能被直接修改,若要修改可以先删除,在插入

B:错误,map是C++98中已存在的,unordered_map是C++11中才有的

C:错误,map和set底层结构都是红黑树,而其底层红黑树在实现时并没有区分是存k模型还是KV 模型

D:错误,map中key是唯一的,每个key都有与之对应的value,经常需要通过key获取value,因此 map为了形象简    单重载了[]运算符, multimap中key是可以重复的,如果重载了[]运算符,给定 一个key时,就没有办法返回     value了,因此,multimap中没有重载[]运算符

19. 关于AVL树的旋转说法正确的是()

A.插入时,AVL树最多只需要旋转两次

B.删除时,只要某个节点的平衡因子不满足特性时 ,只需要对该棵子树进行旋转,就可以使AVL树再次平衡

C.AVL树的节点中必须维护平衡因子,因为要依靠其平衡因子是否需要旋转以维护其平衡性

D.AVL树的双旋转只需要直接使用对应的单旋转即可

  A:正确,即双旋

  B:错误,可能需要旋转多次,子树旋转后,其高度降低了一层,其上层可能也需要跟着旋转

  C:错误,平衡因子不是必须要维护的,在操作时也可以直接通过高度函数来算,只不过比较麻烦

  D:错误,不能直接使用单旋转,因为两个单旋转完成后,还需要对部分节点的平衡因子进行更新

 红黑树是近似的平衡树,没有什么最坏情况,插入的时间复杂度为O(log(N))

要使哈希高效:选择好的哈希函数非常关键

   好的哈希函数可以减少发生冲突的概率

   万一发生冲突,好的处理好戏冲突的方法也比较关键,否则冲突处理不当,也会增加后序元素冲 突的概率

 哈希函数设计原则:

  1. 哈希函数应该尽可能简单

  2. 哈希函数的值域必须在哈希表格的范围之内

  3. 哈希函数的值域应该尽可能均匀分布,即取每个位置应该是等概率的

冲突越多,查找时比较的次数就越多,对平均查找长度影响比较大。

21. 下面关于列表初始化说法正确的是()

A.C++语言从C++98开始,就支持列表方式的初始化

B.列表初始化没有什么实际作用,直接调用对应的构造函数就可以了

C.自定义类型可以支持多个对象初始化,只需要增加initializer_list类型的构造函数即可

D.以下关于c和d的初始化,结果完全相同 // short c = 65535; short d { 65535 };

A:错误,列表初始化是从C++11才开始支持的

  B:错误,列表初始化可以在定义变量时就直接给出初始化,非常方便

  C:正确

  D:错误,不同,列表初始化在初始化时,如果出现类型截断,是会报警告或者错误的

 final 只能修饰派送类的虚函数

有时捕获异常并不是为了处理异常,而是要做一些其他事情,做完后需要将异常重新抛 出,交给该异常的    处理位置去处理

weak_ptr不能单独管理资源,必须配合shared_ptr一块使用,解决shared_ptr中存在的 循环引用问题

C++11中提供的智能指针都只能管理单个对象的资源,没有提供管理一段空间资源的智 能指针

weak_ptr和shared_ptr都是通过引用计数实现,但是在底层还是有区别的 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油,旭杏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值