南阳网站设计,商丘网站制作教程,wordpress和dedecms,搜索网站模板关键字
1.##xff0c;##的用法
#是字符串转换符#xff0c;##是字符串连接符#xff1b;发生在预处理阶段#xff1b;
2.volatile的含义
防止编译器优化#xff0c;告诉编译器每次都去真实地址中读取#xff0c;而不是从寄存器或者缓存中###的用法
#是字符串转换符##是字符串连接符发生在预处理阶段
2.volatile的含义
防止编译器优化告诉编译器每次都去真实地址中读取而不是从寄存器或者缓存中 多线程修改的共享变量中断修改的全局变量硬件寄存器访问
3.static的作用
static修改变量的作用域和生命周期 static修饰全局变量限制它的作用域在本文件 static修饰局部变量会将它的周期变为全局生命周期 static修饰类成员变量该变量变成类的属性 static修饰类成员函数该函数变成全部对象共享的函数不用实例化就可以使用且只能修改静态成员变量
4.为什么static只初始化一次
因为static变量具有全局的生命周期初始化之后不会被销毁所以不用再次初始化
5.extern C 的作用是什么
提示编译器这部分按照c语言去编译
6.const有什么作用
const代表我们的常量修饰之后不可修改且必须初始化
7.什么时候用const
可以修饰一般常量常数组常对象常指针常引用函数常参数函数返回值 指针常量int*const pp不变指向不变 常量指针int const*pconst 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*) (p1)-(char*) p
11.struct 和 union的区别
struct是为所有成员顺序分配空间union是所有成员共享一片空间空间大小等于最大的元素每次只能有一个变量生效 假设32位的机器typedef union {double i; int k[5]; char c;}DATE; 大小8201 20——》24(8字节对齐)typedef struct data( int cat; DATE cow;double dog;too;424(4)8 40
12.struct的对齐规则为什么要对齐
内部对齐变量的起始地址必须是变量大小的整数倍 外部对齐结构体大小必须是最大的基础类型的整数倍 对齐可以提高访问的速度
12.左值和右值是什么
左值和右值的区别在于有没有确定的地址左值可写右值可读
13.短路求值
布尔表达式中第一个表达式如果确定了表达式的结果将不会计算第二个表达式
14.i和i有什么区别是怎么实现的
i复制到了临时的存储空间temp itemp 1return temp i是直接加1i 1return i
内存
1.内存的分配方式
堆上分配栈上分配静态区分配在编译之前完成
2.堆栈的区别
①堆是由用户自己申请和释放的栈是操作系统自动申请和释放的 ②堆是不连续的用链表来进行管理栈是连续的占用内存小生长方向也不同 ③栈的效率比堆更高
3.栈的作用
栈可以用来存局部变量函数参数返回地址寄存器值等一般用于函数调用多线程切换中断和异常时保护现场和恢复线程
4.函数参数压栈顺序
ARM用R0~R3来传递函数参数如果超过了4个那么将用栈来存储参数从右至左最后一个最先入栈第一个参数最后入栈更容易的实现动态变化的参数个数不需要知道参数的个数
5.c如何处理返回值
按值返回按常量引用返回
6.c的内存管理
代码段bss段data段堆文件映射区栈
7.什么是内存泄漏
申请了内存使用完没有释放
申请了一片内存没有指针指向它那它就泄漏了未释放不匹配虚析构循环引用
8.如何防止内存泄漏
①良好的编程习惯申请和释放成对出现 ②使用智能指针 ③使用STL库它们会自动进行内存管理 ④RALL思想超出作用域自动释放
9.如何检测内存泄漏
①日志申请和释放都打印指针地址 ②统计申请和释放都统计次数 ③valgrindvalgrind --leak-checkfull ./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(i0;i4;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 ③使用智能指针
智能指针
C11使用三种智能指针来帮助动态管理内存 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;//p3p4都是指针
如何使用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的默认继承和访问权限全是publicclass有不同的继承和访问权限publicprotectprivate
C中类成员的访问权限
在类内无论是publicprotectprivate都可以访问在类外只能访问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::vectorint source {1, 2, 3, 4, 5};
// 使用移动语义将source向量的内容移动到destination向量
std::vectorint 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::forwardT(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() {}
};
将构造函数和析构函数变成私有成员再写一个静态创建类和释放类的函数 位处理容器和算法数据结构待补充