#int main(int argc, char *argv[])里的参数,你了解吗?
参数的含义是程序在命令行下运行的时候,输入了argc 个参数,每个参数以char*类型存入 argv[],第一个参数为程序的名称。
#volatile关键字的作用?
volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,系统总是重新从它所在的内存读取数据。可以用在多线程中,每次读取到修改后的值。
#如果有一个空类,它会默认添加哪些函数?
|
|
只有你需要用到这些函数并且你又没有显示的声明这些函数的时候,编译器才会贴心的自动声明相应的函数。
https://developer.aliyun.com/article/3763
#C++中标准库是什么?
C++ 标准库可以分为两部分:
标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言。
- 输入/输出 I/O、字符串和字符处理、数学、时间、日期和本地化、动态分配、其他、宽字符函数
面向对象类库: 这个库是类及其相关函数的集合。
- 标准的 C++ I/O 类、String 类、数值类、STL 容器类、STL 算法、STL 函数对象、STL 迭代器、STL 分配器、本地化库、异常处理类、杂项支持库
https://www.runoob.com/cplusplus/cpp-standard-library.html
#const char* 与string之间的关系?
string 是c++标准库提供的字符串类,封装了对字符串的操作
const char *是指向一个常量字符串的指针
可以用const char*给string类初始化,用string.c_str()给const char *初始化。
三者的转化关系如下所示:
|
|
#你什么情况用指针当参数,什么时候用引用,为什么?
用指针的情况一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向),其他情况一般都使用引用,它可以避免判断是否为空提高效率,并且不会像普通的值传递还需要拷贝实参。
https://blog.csdn.net/wyg1065395142
https://blog.csdn.net/lyd_253261362
#静态绑定和动态绑定?
- 静态类型:对象在声明时采用的类型,在编译期既已确定;
- 动态类型:通常是指一个指针或引用,目前所指对象的类型,是在运行期决定的;
- 静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
- 动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期;
- 在继承体系中只有虚函数使用的是动态绑定,其他的全部是静态绑定;
#如何设计一个计算仅单个子类的对象个数?
1、为类设计一个static静态变量count作为计数器;
2、类外初始化count;
3、在构造函数~~、拷贝构造函数、赋值构造函数~~中对count进行+1;
4、在析构函数中对count进行-1;
#怎么快速定位错误出现的地方?
查看错误信息和日志:首先,仔细阅读错误信息和日志,它们通常会提供关于错误类型、发生位置和相关调用栈的信息。错误信息可能包含文件名、行号、函数名等,这些信息可以帮助你快速定位到错误的源代码位置。
使用调试器:调试器是一种强大的工具,可以逐行跟踪代码的执行过程,查看变量的值、调用堆栈等信息。通过在出现错误的地方设置断点,你可以在运行时停止程序并检查当前的状态,帮助你找到问题所在。
日志输出和断言:在代码中适当地添加日志输出和断言语句,可以帮助你追踪程序的执行过程,并在特定条件下中断程序执行。通过在关键位置输出日志信息,你可以了解程序的执行流程和变量的值,从而更容易定位错误。
缩小搜索范围:如果你已经确定错误发生在某个函数或代码块内部,可以采用二分法或逐步注释法来缩小搜索范围。通过逐渐注释掉代码段或只保留关键部分,可以确定错误发生的具体位置。
使用工具和技术:利用各种可用的工具和技术来辅助定位错误,如代码静态分析工具、内存泄漏检测工具、性能分析器等。这些工具可以提供更详细的分析和报告,帮助你找出潜在的问题所在。
与他人讨论和协作:如果你遇到困难或无法确定错误的来源,寻求他人的帮助是一个明智的选择。与其他开发者或论坛社区交流,描述你的问题和尝试过的解决方法,他们可能会提供新的思路和建议。
#成员初始化列表会在什么时候用到?它的调用过程是什么?
当初始化一个引用成员变量时;
初始化一个const成员变量时;
初始化没有默认构造函数的成员对象或者基类对象;
考虑性能的时候,列表初始化减少一次拷贝
调用过程?不知道,初始化参数过程:按照类中定义变量的顺序进行初始化 代码
#进行函数参数以及返回值传递时,使用引用的好处有哪些?
对比值传递,引用传参的好处:
- 在函数内部可以直接对实参修改
- 提高函数调用和运行的效率(因为没有了传值和生成副本的时间和空间消耗)
用引用作为返回值最大的好处就是在内存中不产生被返回值的副本。
但是不能返回局部变量的引用。因为函数返回以后局部变量就会被销毁。
#说一说strcpy、sprintf与memcpy这三个函数的不同之处
- 操作对象不同
① strcpy的两个操作对象均为字符串
② sprintf的操作源对象可以是多种数据类型,目的操作对象是字符串
③ memcpy的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。
- 执行效率不同
memcpy最高,strcpy次之,sprintf的效率最低。
- 实现功能不同
① strcpy主要实现字符串变量间的拷贝
② sprintf主要实现其他数据类型格式到字符串的转化
③ memcpy主要是内存块间的拷贝。
|
|
#将引用作为函数参数有哪些好处?
- 在函数内部可以对此参数进行修改
- 提高函数调用和运行的效率(因为没有了传值和生成副本的时间和空间消耗)
- 用指针的情况
- 一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),
- 二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向),
#你知道数组和指针的区别吗?
- 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数。
- 在向函数传递参数的时候,如果实参是一个数组,数组会退化成指针,指向数组的首地址。
- 对数组取地址操作后,必须用pointer to array来接受。
#如何阻止一个类被实例化?有哪些方法?
- 将类定义为抽象基类(抽象类含有纯虚函数)
- 构造函数声明为private
#如何禁止程序自动生成拷贝构造函数?
|
|
#拓展:A a() 和 A a的区别
不要想当然的认为a()会调用默认构造函数,实际上它只是声明,而a才是会调用那个默认构造函数,即定义。
https://blog.csdn.net/m0_37166947/article/details/72856841
在C++中,A a()
和A a
有不同的含义和行为。
A a()
:- 这是一个函数声明的语法,而不是对象的定义或创建。
- 它声明了一个名为
a
的函数,该函数没有参数并返回类型为A
的值。 - 这种语法在某些情况下可能会引起误解,因为它看起来像是在创建一个名为
a
的对象,但实际上它是一个函数声明。 - 要创建一个对象,应该使用
A a;
或A a{};
的形式。
A a
:- 这是一个对象的定义和创建。
- 它声明了一个名为
a
的对象,类型为A
。 - 如果
A
是一个类类型,则会调用默认构造函数来初始化对象a
。 - 对象
a
的生命周期将根据其定义的作用域和存储位置进行管理。
from GPT3.5
#Debug和Release的区别?
调试版本,包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。Debug模式下生成两个文件,除了.exe或.dll文件外,还有一个.pdb文件,该文件记录了代码中断点等调试信息;
发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的。(调试信息可在单独的PDB文件中生成)。Release模式下生成一个文件.exe或.dll文件。
实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
#main函数的返回值?
程序运行过程入口是main函数,main()函数返回值类型必须是int,这样返回值才能传递给程序激活者(如操作系统)表示程序正常退出。
main(int args, char **argv) 参数的传递。参数的处理,一般会调用getopt()函数处理,但实践中,这仅仅是一部分,不会经常用到的技能点。
#写一个比较大小的模板函数
|
|
#strcpy函数和strncpy函数的区别?哪个函数更安全?
- 函数原型
|
|
- strcpy函数: 如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况。
- strncpy函数:用来复制源字符串的前n个字符,但是它不会在目标字符串追加结束符,容易出现意想不到的输出结果。如果n比较大,会一直填充结束符直到n,效率不太好。 https://blog.csdn.net/qq_26093511/article/details/73338036
因此推荐使用strdup,在堆上开辟,或者strdupa,在栈上开辟,或者用string