121、在进行函数参数以及返回值传递时,可以使用引用或者值传递,其中使用引用的好处有哪些?
对比值传递,引用传参的好处:
- 在函数内部可以对此参数进行修改;
- 提高函数调用和运行的效率(因为没有了传值和生成副本的时间和空间消耗)
值传递:
- 函数的参数实质就是形参,不过这个形参的作用域只是在函数体内部,也就是说实参和形参是两个不同的东西,要想形参代替实参,肯定有一个值的传递。
- 函数调用时,值的传递机制是通过“形参=》实参”来对形参赋值达到传值目的,产生了一个实参的副本。
- 即使函数内部有对参数的修改,也只是针对形参,也就是那个副本,实参不会有任何更改。
- 函数一旦结束,形参生命也宣告终结,做出的修改一样没对任何变量产生影响。
用引用作为返回值最大的好处就是在内存中不产生被返回值的副本。
但是有以下的限制:
- 不能返回局部变量的引用。因为函数返回以后局部变量就会被销毁;
122、说一说strcpy、sprintf与memcpy这三个函数的不同之处
1、操作对象不同
- strcpy的两个操作对象均为字符串;
- sprintf的操作源对象可以是多种数据类型,目的操作对象是字符串;
- memcpy的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。
2、执行效率不同
- memcpy最高,strcpy次之,sprintf的效率最低。
3、实现功能不同
- strcpy主要实现字符串变量间的拷贝;
- sprintf主要实现其他数据类型格式到字符串的转化;
- memcpy主要是内存块间的拷贝。
123、将引用作为函数参数有哪些好处?
1、传递引用给函数与传递指针的效果是一样的。
- 被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
2、使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;
- 而使用值传递,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;
- 如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
3、使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;
指针传参在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
124、你知道数组和指针的区别吗?
- 数组在内存中是连续存放的,开辟一块连续的内存空间;
- 数组所占存储空间:sizeof(数组名);数组大小:sizeof(数组名)/sizeof(数组元素数据类型);
- 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof( p ),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。
- 编译器为了简化对数组的支持,实际上是利用指针实现了对数组的支持。具体来说,就是将表达式中的数组元素引用转换为指针加偏移量的引用。
- 在向函数传递参数的时候,如果实参是一个数组,那用于接受的形参为对应的指针。也就是传递过去是数组的首地址而不是整个数组,能够提高效率;
- 在使用下标的时候,两者的用法相同,都是原地址加上下标值,不过数组的原地址就是数组首元素的地址是固定的,指针的原地址就不是固定的。
125、如何阻止一个类被实例化?有哪些方法?
- 将类定义为抽象基类或者将构造函数声明为private;
- 不允许类外部创建类对象,只能在类内部创建对象;
126、如何禁止程序自动生成拷贝构造函数?
class noncopyable
{
private:
noncopyable(const noncopyable&) = delete;
void operator=(const noncopyable&) = delete;
protected:
noncopyable() = default;
~noncopyable() = default;
};
class student: noncopyable
{
public:
student(){};
}
class noncopyable
的基本思想:
- 把构造函数和析构函数设置protected权限,这样子类可以调用,但是外面的类不能调用,那么当子类需要定义构造函数的时候不至于通不过编译。
- 最关键的是noncopyable把拷贝构造函数和拷贝赋值函数做成了private的,继承自noncopyable的类在执行拷贝操作时会调用基类的拷贝操作,但是基类的拷贝操作是private的,因此无法调用,引发编译错误。
127、你知道Debug和Release的区别是什么吗?
Debug:
- 调试版本,包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。
- Debug模式下生成两个文件,除了.exe或.dll文件外,还有一个.pdb文件,该文件记录了代码中断点等调试信息;
Release:
- 发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优的。(调试信息可在单独的PDB文件中生成)。
- Release模式下生成一个文件.exe或.dll文件。
实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
128、main函数的返回值有什么值得考究之处吗?
- 程序运行过程入口点main函数,main()函数返回值类型必须是int,这样返回值才能传递给程序激活者(如操作系统)表示程序正常退出。
- main(int args, char **argv) 参数的传递。参数的处理,一般会调用getopt()函数处理,但实践中,这仅仅是一部分,不会经常用到的技能点。
129、模板会写吗?写一个比较大小的模板函数
#include<iostream>
using namespace std;
template<typename type1,typename type2>//函数模板
type1 Max(type1 a,type2 b)
{
return a > b ? a : b;
}
void main()
{
cout<<"Max = "<<Max(6,5)<<endl;
}
130、strcpy函数和strncpy函数的区别?哪个函数更安全?
函数原型:
char* strcpy(char* strDest, const char* strSrc)
char *strncpy(char *dest, const char *src, size_t n)
strcpy函数:
- 如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strncpy()来取代。
strncpy函数:
- 用来复制源字符串的前n个字符,src 和 dest 所指的内存区域不能重叠,且 dest 必须有足够的空间放置n个字符。