目录
const的作用有哪些,谈一谈你对const的理解?
const关键字,声明常量和约束对象的不可修改性。
const修饰的变量不能够在作为左值!!初始化完成后,值不能被修改!!
可以修饰基本数据类型(常量和数组)、指针、函数(参数、返回值)、成员函数、类中变量。
1 const修饰一般常量和数组,const可以在类型说明符前也可以在类型说明符后:
2 指针:常量指针和指针常量见下一题
3 函数参数:
修饰形参,函数体内不能修改形参的值了。const只能修饰输入作用的参数。
参数为指针:加上const 修饰之后,保护了这一块内存地址不被修改,如果刻意修改这一块内存,编译器会报错。
参数为引用:加上const 之后既起到了保护作用,也提高了程序效率。直接按值传递会产生临时对象,随后调用拷贝构造函数,函数结束进行析构释放资源,使用引用就不会产生临时变量(别名)
4 修饰函数返回值:不能修改返回值
返回值为指针:接收的变量也必须是const类型
返回值为引用:不常用
5 修饰成员函数:只有成员函数才能加,要求成员函数不修改成员变量
const函数的使用规则:
1.const对象只能访问const成员函数,非const对象可以访问任何成员函数;
2.const成员函数可以访问所有成员变量,但是只能访问const成员函数;非const成员函数可以访问任何成员变量,任何成员函数;
3. 如果函数的名称、参数、返回值都一样但是一个有const一个没const也可构成重载;
4.const成员函数不能修改const成员变量,除非成员变量用mutable。
const的好处:
1.保护常量;2.便于类型检查":const常量有类型,宏没有类型;3.为函数重载提供参考;4 节省空间避免不必要的内存分配:const常量在内存上只有一份拷贝,宏定义的常量在内存中有若干个;5提高效率:const常量保存在符号表中,编译期常量。
在c和c++中区别:
在c中,const修饰变量本质还是变量,只是它不可在做左值,也就是不能通过直接赋值修改变量,但是还是可以通过指针类型转换等手段修改。
在C++中 ,在编译的时候,当碰到用const修饰的变量时,编译器是直接将变量的值和变量的符号对应起来一起存到符号表。
在c++中编译器不会给const a分配内存,但在c中会。
指针常量和常量指针?
int const *p或const int *p常量指针:是一个常量,必须初始化,不可以修改所指向的变量值,指针指向可以改变。
int *const p指针常量:是一个指针,不能改变指针指向,但可以通过指针修改所指向变量的值。
const和*位置:const在左边就是常量指针,量不变向可变,const在右变就是向不变量可变。
条件变量为什么要配合锁使用?
为了实现多线程之间的同步和线程通信。因为多线程中,常见需要等待一个线程满足某个条件之后才继续运行,而这个条件是由另外一个线程负责满足这个条件。
1. 保护共享数据:多线程需要保护共享资源的安全性,使用锁可以保证同一时间只有一个线程可以对共享资源访问或修改数据。
2. 防止竞态条件:多个线程对共享资源读写造成不确定结果;
3. 线程等待和通知:当一个线程满足条件,可以使用条件变量阻塞线程执行,并释放锁,其他线程执行到满足条件时,在通过条件变量通知阻塞线程继续运行。
static作用?什么情况下用static?
static被修饰的变量或函数时这个变量或函数就会成为一个静态变量,改变标识符的作用域和生命周期,使其具有静态的特性。使用 static
可以实现数据的共享、限制作用域、提供全局访问点等功能。
静态变量:在函数内部使用声明变量为静态变量。静态变量具有静态存储周期,在整个程序的生命周期内都存在。默认初始化为0或空,第一次执行进行初始化,之后的函数调用不会再初始化。
静态函数:静态函数的作用域被限制在调用它的源文件中,不可在被别的源文件调用,可以避免与其他源文件中的同名函数冲突。
静态成员变量:在类中使用static关键字声明的成员变量称为静态成员变量。属于类本身而不是类的实例。在所有类的实例对象中都是共享的,具有相同的值。
静态成员函数:不属于类的实例,可直接通过类名调用无需创建实例,它不妨实例的成员变量,只访问静态成员变量或其他静态成员函数。
全局变量和局部变量的区别?
全局变量 | 局部变量 | |
作用域 | 整个程序 | 限定代码块 |
生命周期 | 程序开始执行到结束 | 所属代码块执行期间 |
存储位置 | 静态存储区 | 栈内存中 |
初始化 | 可以显式初始化或隐式初始化 未初始化的默认为0或者空 | 不会被自动初始化 需要显式赋值或初始化 |
可见性访问权限 | 任何函数,全局可见 | 所属代码块内部,局部可见 |
宏定义的作用是什么?#define
在编译之前将源代码中的文件进行简单替换。
定义常量:通过宏定义可以为某个值定义一个常量,以便在程序中多次使用,避免了手动多次输入相同的数值或字符串。
定义函数:简单的函数或代码片段。
实现条件编译:宏定义可以根据条件的真假来选择性地包含或排除一些代码,实现条件编译,以便根据不同的编译选项在不同的情况下编译不同的代码。
提高代码的可维护性:通过宏定义可以定义一些具有描述性的名称,使代码更易于阅读和理解,提高代码的可维护性。
typedef和define区别?
typedf | #define | |
语法形式 | 为现有类型创建别名 | 替换文本 |
作用范围 | 限于类型定义 | 可以在任何地方定义宏, 且在整个文件中都有效 |
类型安全性 | 类型安全的可以进行 类型检查和编译器验证 | 简单的文本替换,不进行类型检查 |
可读性和调试 | 都可提高可读性 | 都可提高可读性 |
内存对齐的概念?为什么会有内存对齐?
数据在内存中存储时的起始地址需要符合一定规则,通常是按照数据类型的大小进行对齐。为了提高访问效率和性能。
c++11以后引入两个关键字 alignas (opens new window)与 alignof (opens new window)。其中alignof
可以计算出类型的对齐方式,alignas
可以指定结构体的对齐方式。
1. 访问对齐内存的数据更高效:许多处理器要求在特定地址上对齐才能进行高效访问,否则处理器可能要进行多次访问或者执行额外的指令来读取或写入数据。
2. 缓存行对齐,现代计算机通常采用层次化的缓存结构,其中最小的缓存单位是缓存行。如果数据跨越多个缓存行,就会导致缓存行的浪费和性能下降。通过对齐数据,可以确保数据在缓存行中连续存储,提高缓存的命中率和访问速度。
inline函数特点?优缺点?
内联函数(inline function)是一种在编译器中展开的函数,它在函数调用的地方直接替换为函数体(直接展开),以减少函数调用的开销。
优点:提高程序的执行效率,避免函数调用开销,减少了函数调用的栈帧保存和恢复操作,函数调用涉及到堆栈操作和上下文切换。
缺点:增大代码大小,内联函数的展开会导致代码膨胀。
适用于频繁调用的函数体较小的函数。
如何避免野指针?
野指针指的是指向无效内存地址的指针。没有正确初始化或者已经指向的内存已被释放。
出现地方:在未初始化的指针、悬挂指针、指向局部变量的指针出现;
解决办法:1.及时初始化指针,定义时及时初始化为nullptr或者一个有效的地址;
2.动态内存管理,使用智能指针(如 std::unique_ptr
和 std::shared_ptr
)来管理内存;
3. 避免悬挂指针,在指针所指的对象被释放后,要避免继续使用该指针,可以在释放指针后将其设置为nullptr,或者及时将其指向新的有效对象。
4.使用引用计数智能指针,使用引用计数智能指针来共享对象所有权,确保在所有引用都被释放后对象才会被销毁。
如何计算结构体长度?
sizeoif运算符,返回给定类型或变量的自己大小,可以使用#pragma pack指令或编译器对齐选项来控制结构体的对齐方式。
sizeof和strlen有什么区别?
sizeof是一个运算符,用于计算类型或变量的字节大小。在编译时确定,返回以字节为单位到的大小。
strlen是一个函数,用于计算字符串长度,即字符串中字符个数。在运行时确定的。对于非字符串类型的字符数组或指针,使用strlen
是不安全的,因为它要求字符串以\0
结尾。
如何用C实现C++面向对象特征(封装、继承、多态)?
1. 封装:
使用结构体struct来封装数据,并将相关的操作函数和结构体关联;
使用函数来操作结构体,实现对数据的访问和操作控制;
通过将结构体的定义和操作函数声明放在不同的头文件中,实现私有和公共成员的区分。
2. 继承:
使用包含composition来模拟继承关系。创建一个结构体,其中包含其他结构体作为成员,实现对其他结构体的组合和扩展。
使用函数指针或函数回调来实现类似虚函数的机制,使得可以在运行时根据对象类型调用相应函数
3. 多态:
使用函数指针或函数回调,将不同类型的对象绑定到相同的函数接口上,实现对不同对象的多态调用。
使用函数指针数组来实现类似虚函数表的机制,通过不同的对象类型索引不同的函数。
memcpy怎么实现让它效率更高?
按字节进行的,可以用于任何类型的数据拷贝。
1.使用对齐的指针;要求源地址和目标地址都是对齐的。
2.批量拷贝:对于大块的内存拷贝可以将拷贝操作分成多个较小的拷贝,提高效率。
3.优化选项。
extern有什么作用,extern C有什么作用?
关键字,extern
用于声明一个全局变量或函数,可以在当前文件中引用其他文件中定义的全局变量或函数。
C++还可以用extern
关键字来声明一个外部的C语言函数,以便能够在C++代码中使用C语言编写的函数。指定一段C语言代码的链接方式