关键字

1."#","##"的用法

#是字符串转换符,##是字符串连接符;发生在预处理阶段;

2.volatile的含义

防止编译器优化,告诉编译器每次都去真实地址中读取,而不是从寄存器或者缓存中;
多线程修改的共享变量,中断修改的全局变量,硬件寄存器访问

3.static的作用

static修改变量的作用域和生命周期;
static修饰全局变量,限制它的作用域在本文件;
static修饰局部变量,会将它的周期变为全局生命周期;
static修饰类成员变量,该变量变成类的属性;
static修饰类成员函数,该函数变成全部对象共享的函数,不用实例化就可以使用,且只能修改静态成员变量;

4.为什么static只初始化一次?

因为static变量具有全局的生命周期,初始化之后不会被销毁,所以不用再次初始化;

5.extern C 的作用是什么?

提示编译器这部分按照c语言去编译

6.const有什么作用?

const代表我们的常量,修饰之后不可修改,且必须初始化

7.什么时候用const?

可以修饰一般常量,常数组,常对象,常指针,常引用,函数常参数,函数返回值;
指针常量:int*const p;p不变,指向不变
常量指针:int const*p;const int*p;*p不变,指向的值不变
指向常量的常量指针:const int* const p
常量有可能存在:只读数据段,堆(动态分配),栈(局部常量),静态区(静态常量);

8.new/malloc/delete/free的区别?

①new和delete不需要自己计算大小,malloc和free需要
②new和delete会调用构造和析构,但malloc只是单纯的分配和释放内存
③new和delete会返回对应类型的指针,malloc和free返回void*;
new = malloc + 构造函数 + 强制类型转换;

9.strlen和sizeof的区别?

①库函数和关键字
②运行期和编译期
③计算字符串的长度,计算操作数的长度;strlen("\0") =0sizeof("\0")=2

10.不使用size of,如何求int占用的字节数?

int *p;
#define mysizeofint(value) (char*) &(p+1)-(char*) &p 

11.struct 和 union的区别?

struct是为所有成员顺序分配空间,union是所有成员共享一片空间,空间大小等于最大的元素,每次只能有一个变量生效;
假设32位的机器
typedef union {double i; int k[5]; char c;}DATE; 大小:8,20,1 = 20——》24(8字节对齐)
typedef struct data( int cat; DATE cow;double dog;too;4+24+(4)+8 = 40 

12.struct的对齐规则?为什么要对齐?

内部对齐:变量的起始地址必须是变量大小的整数倍;
外部对齐:结构体大小必须是最大的基础类型的整数倍;
对齐可以提高访问的速度;

12.左值和右值是什么?

左值和右值的区别在于有没有确定的地址;左值可写右值可读;

13.短路求值?

布尔表达式中,第一个表达式如果确定了表达式的结果,将不会计算第二个表达式

14.++i和i++有什么区别?是怎么实现的?

++i复制到了临时的存储空间,temp = i;temp += 1;return temp;
i++是直接加1;i +=1;return i;

内存

1.内存的分配方式?

堆上分配,栈上分配,静态区分配(在编译之前完成);

2.堆栈的区别?

①堆是由用户自己申请和释放的;栈是操作系统自动申请和释放的
②堆是不连续的,用链表来进行管理;栈是连续的,占用内存小;生长方向也不同;
③栈的效率比堆更高;

3.栈的作用?

栈可以用来存局部变量,函数参数,返回地址,寄存器值等;一般用于函数调用多线程切换中断和异常时保护现场和恢复线程;

4.函数参数压栈顺序?

ARM用R0~R3来传递函数参数,如果超过了4个,那么将用栈来存储参数从右至左,最后一个最先入栈,第一个参数最后入栈,更容易的实现动态变化的参数个数,不需要知道参数的个数;

5.c++如何处理返回值?

按值返回,按常量引用返回;

6.c++的内存管理

代码段,bss段,data段,堆,文件映射区,栈;

7.什么是内存泄漏?

申请了内存,使用完没有释放;

申请了一片内存,没有指针指向它,那它就泄漏了;(未释放,不匹配,虚析构,循环引用)

8.如何防止内存泄漏?

①良好的编程习惯,申请和释放成对出现;
②使用智能指针;
③使用STL库,它们会自动进行内存管理;
④RALL思想,超出作用域自动释放;

9.如何检测内存泄漏

①日志:申请和释放都打印指针地址;
②统计:申请和释放都统计次数;
③valgrind:valgrind --leak-check=full ./leak 分析代码,解决问题;

指针

数组指针和指针数组的区别?

数组指针是指指向数组的指针;输出:5

#include <stdio. h>
#include <stdlib. h>
void main()
{
 int b[12]={1,2,3,4,5,6,7,8,9,10,11,12};
 int (*p)[4];
 p = b;
 printf("%d\n", **(++p);
}


指针数组是指数组存储的都是指针;输出:1234

#include <stdio.h>
int main()
 {
    int i;
    int *p[4];
    int a[4]={1,2,3,4};
    p[0] = &a[0];
    p[1] = &a[1];
    p[2] = &a[2];
    p[3] = &a[3];
    for(i=0;i<4;i++)
        printf("%d",*p[i]);
    printf("\n"); 
    return 0;
}

函数指针和指针函数有什么区别?

函数指针是指一个指向函数地址的指针;
 

 int(*p)(int, int);  //定义一个函数指针
 int a, b;
 p = Max;  //把函数Max赋给指针变量p, 使p指向Max函数
 c = (*p)(a, b);  //通过函数指针调用Max函数

指针函数表示函数返回值是一个指针;         

int *pfun(int, int);

数组名和指针的区别是什么?

数组名是数组第一个元素的地址,内存偏移量是元素的大小,通过下标,数组名+元素偏移量访问;
指针保存的是地址,内存偏移量是4字节,是间接访问需要解引用*;

指针和引用的区别是什么?

①指针是实体,引用是别名;
②指针可以为空,引用不能为空;
③指针可以改变指向,引用只能初始化一次;
④自增,++指针是指向下一个地址,引用是变量加1;
⑤sizeof,指针是4字节,引用是变量大小

野指针是什么?

野指针指的是指向不可用内存的指针;当指针创建的时候,默认值是随机的;当指针free掉的时候,只free了指向的内存,指针本身没有释放,得指向null;

如何避免野指针?

①指针初始化;
②指针用完之后释放内存,将指针指向NULL;
③使用智能指针;

智能指针

C++11使用三种智能指针来帮助动态管理内存,
unique:独享对象的指针所有权
shared:共享对象的指针所有权,引用计数,拷贝的时候引用计数+1,释放的时候-1,当为0,就释放对象;
weak:解决循环引用的问题;

智能指针的内存泄漏如何解决?

weak_ptr不会影响引用计数,即使存在循环引用,引用计数也可以降到0,从而正确释放对象;

预处理

typedef和define有啥区别?

①typedef是关键字,有类型检查的功能;define是预处理指令,没有类型检查的功能,只是简单的文本替换;
②typedef是为变量类型起别名,但define不仅可以为变量类型起别名还可以定义常量,开关等
③对指针的操作不同:
 

#define INTPTR1 int*
typedef int* INTPTR2;
INTPTR1  pl, p2;//p1是指针,p2是int
INTPTR2 p3, p4;//p3,p4都是指针

如何使用define声明常数?

#define SECOND_PER_YEAR (60*60*24*365UL)

#include<>和#include""的区别?

<>从标准库的路径查找,系统文件比较快;""从用户工作路径开始找,适用自定义文件;

头文件的作用?

①封装保护:通过头文件来调用库函数;
②头文件能加强类型安全检查;

在头文件中定义静态变量和全局变量可行吗?

不可以,这样会使得每个包含头文件的cpp文件都会单独存在一个静态/全局变量,引起空间浪费和链接错误;

写一个标准宏,MIN?

#define MIN(A,B) ((A)<=(B)?(A):(B))

不使用流程控制语句,如何打印1-1000?

#include <stdio.h>
#define A(x) x;x;x;x;x;x;x;x;x;x;
int main(){
    int n = 1;
    A(A(A(printf(%d,n++))));
    return 0;
}

变量

全局变量和局部变量的区别?

①生命周期
②作用域
③存储位置

全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?

不建议;一般我们是在c文件中声明全局变量,然后.h extern全局变量;

局部变量能否和全局变量重名?

能,在局部变量的作用域中会屏蔽全局变量;

面向对象

面向对象和面向过程的区别?

面向对象:将对象作为程序的基本单位,对象包含了数据和操作数据的函数,更能模拟客观世界,拥有更好的数据封装,代码的灵活性和复用性也更高;
面向过程:将程序看出一系列命令的集合,一组函数的顺序执行;

面向对象的基本特征?

抽象:将数据或过程抽象成一个实体;
继承:鼓励类的重用,表述共性;
封装:限制对数据的访问只能通过开放的接口;
多态:不同类对象对相同的消息做出的不同响应;

strcut和class的区别是什么?

struct的默认继承和访问权限全是public,class有不同的继承和访问权限,public,protect,private;

C++中类成员的访问权限?

在类内,无论是public,protect,private都可以访问;在类外,只能访问public的;

C++空类默认产生哪些类成员函数?

class Empty
{
  public:
  Empty(); // 构造函数
  Empty( const Empty& ); // 拷贝构造函数
  ~Empty(); // 析构函数
  Empty& operator=( const Empty& ); // 赋值运算符
  Empty* operator&(); // 取址运算符
  const Empty* operator&() const; // 取址运算符 const
};

int main() {
    Empty a; // 调用构造函数

    Empty b(a); // 调用拷贝构造函数
    Empty* ptr = &b; // 隐式调用取址运算符

    Empty c;
    c = a; // 调用赋值运算符

    const Empty* constPtr = &c; // 隐式调用 const 取址运算符

    return 0;
}

拷贝赋值函数的形参能否进行值传递?

可以,但会调用多一次拷贝构造,并不会无限递归;产生额外的赋值;

构造函数没有返回值,怎么知道对象是否构造成功?

如果构造失败,构造函数会抛出异常;如果已经发生了部分构造,已经完成构造的子对象将会逆序被析构;

初始化列表和构造函数初始化的区别?

初始化列表是直接初始化类的成员,构造函数初始化是对类的成员进行赋值

哪些情况智能初始化列表,不能用赋值?

当类中含有const和&引用时,只能初始化,不能对它赋值;
②当类成员是没有默认构造函数的类
③当基类没有默认构造函数,

析构函数作用是什么?

完成对象删除之前的清理工作;

虚函数是什么?

虚函数是一个可以在派生类重写的函数,主要用于实现多态;通过基类指针,指向不同的对象就可以调用相应的虚函数;

C++如何实现动态多态?虚函数表是如何实现运行时多态的?

每个对象内部都有一个虚函数表指针,指向本类的虚函数表的内存地址
每个类的虚函数表会将函数地址按顺序存入,当子类重写父类虚函数的时候,虚函数对应位置的函数会被子类重写的虚函数覆盖
在基类指针指向派生类的时候,虚函数表指针会表面具体调用的函数是哪个;

重载(静态多态)和覆盖(动态多态)有啥区别?

①覆盖是父类子类之间的关系,重载是同一个类的关系;
②覆盖是一对方法之间的关系,重载是多个方法之间的关系;
③覆盖是由对象来决定的,重载是由调用的形参和实参;

纯虚函数指的是什么?

纯虚函数指的是没有办法在基类给出的虚函数有意义的实现,如动物;
但在派生类中必须实现,否则无法实例化;如老虎
拥有纯虚函数的类叫抽象类,抽象类不能生成对象;

静态函数和虚函数的区别?

静态函数在编译期就确定了,但虚函数是在运行时动态绑定的。虚函数用虚函数表机制,调用的时候会增加一次内存开销;

C++如何阻止一个类被实例化?

使用抽象类或将构造函数声明为private;

什么函数不能声明为虚函数?

①普通函数;②构造函数;③内联成员函数;④静态成员函数;⑤友元函数

为什么析构函数必须是虚函数?为什么默认不是?

当一个类需要作为父类的时候,析构函数就需要声明为虚函数,这样可以使得基类指针释放的时候,也可以析构掉子类空间,防止内存泄漏;
因为不是所有类都会成为父类,虚函数需要虚函数表指针和虚函数表,是会占用空间的,没有继承关系的类,其实不用浪费这个资源;

析构函数可以virtual,构造函数不能,为什么?

虚函数是为了继承产生多态,运行时根据对象类型绑定函数;析构函数运行之前对象还没建立,不存在动态绑定一说;

类成员变量的初始化顺序?

①基类静态成员变量(类外)
②派生类静态成员变量 (类外)
③初始化列表:初始化顺序跟定义成员变量的顺序有关 / 构造函数:与构造函数中的位置有关;

类的内存分布?

当一个类为另一个类的成员变量时,如何对其初始化?

class ABC
{
public:
    ABC(int x, int y, int z); 
private : 
    int a; 
    int b; 
    int c;
};
class MyClass
{
public:
    MyClass():abc(1,2,3)
   {
   
    } 
private:
    ABC abc;
};

C++类内可以定义引用数据成员吗?

可以,但必须要用初始化列表初始化;

什么是右值引用,什么是左值引用?

左值能取地址,右值不能取地址;
左值引用指向具有标识符的对象,用于传统的引用操作;
右值引用在移动语义和完美转发场景;
 

std::vector<int> source = {1, 2, 3, 4, 5};
// 使用移动语义将source向量的内容移动到destination向量
std::vector<int> destination = std::move(source);
//std::move(source)将source的内容移动到destination,避免了不必要的拷贝操作;
//现在source={},destination = {1, 2, 3, 4, 5}


// 函数模板,完美转发参数到另一个函数
template <typename T>
void forwarder(T&& arg) {
    receiver(std::forward<T>(arg));
}

// 接受转发参数的函数
void receiver(int&& x) {
    std::cout << "Received rvalue: " << x << std::endl;
}
//左值不会
void receiver(const int& x) {
    std::cout << "Received lvalue: " << x << std::endl;
}

什么是深拷贝?什么是浅拷贝?

浅拷贝只拷贝指针,指向同一片内存;
深拷贝不仅拷贝指针,内存也拷贝了一份,指针指向各自的内存;

Public继承、protected继承、private继承的区别?

Public:派生类所有成员继承了基类的访问权限;
Protect:基类的公有成员在派生类中都变为保护成员;
Private:共有成员和保护成员都作为派生类的私有成员;

基类的构造函/析构函数数能否被派生类继承?

不会被继承;派生类会调用基类的构造和析构函数,但不是继承;

什么是友元?

友元提供了一种普通函数访问类的保护和私有成员的机制;
友元函数:普通函数可以访问B类的私有/保护成员
友元类:A类的类成员函数可以访问B类私有/保护成员;

C++能设计不能被继承的类吗?

{
public :      
static FinalClass1* GetInstance()     
 {          
   return new FinalClass1;    
 }        
static void DeleteInstance( FinalClass1* pInstance)    
 {            
delete pInstance;         
   pInstance = 0;     
 }  
private :      
FinalClass1() {}     
~FinalClass1() {}
};
将构造函数和析构函数变成私有成员,再写一个静态创建类和释放类的函数;

位处理,容器和算法,数据结构待补充

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部