1、数组名和指针的区别?
答:数组名类似一个const指针,不可被赋值;而指针是一个变量,可以被赋值
sizeof运算符对数组名的运算结果是数组的大小;对指针或者const指针的运算结果是指针自身占据空间大小
综上所述,数组名是一个符号,唯一标记数组空间的首地址
2、c/c++常见算术类型的大小?
答:算术类型的尺寸在不同机器上有所差别。一个char的大小和一个机器字节相等。
一个int至少和一个short一样大,一个long至少和一个int一样大,一个long long至少和一个long一样大。
通常,char8位,short16位,int32位,long32位/64位,long long64位,float32位,double64位
3、定义和声明的联系和区别?
答:声明使得名字为程序所知,定义负责创建与名字关联的对象
声明可以多次,定义只能一次
声明和定义可以融合
(extern在不进行初始化的情况下表示声明)
4、什么是对象?
答:一块能存储数据并具有某种类型的内存空间
5、什么是形参?什么是实参?
答:形参是函数被调用时用于接收实参值的变量
实参是在调用函数时传递给函数的参数
6、什么是引用?和指针的区别?
答:引用即别名,是为一个已经存在的对象所起的另外一个名字(引用占用内存,大小同指针的大小)
和指针的区别:1.引用必须被初始化且初始化后不可改变,指针相反
2.引用不能为空,指针可以
3.引用的两个主要用途:作为函数参数或作为函数返回值
7、c语言中static关键字的作用有哪些?
答:在C中,static主要定义全局静态变量(限制作用域)、定义局部静态变量(改变存储区)、定义静态函数(限制作用域)。
(还可以用于定义c++中静态函数和静态成员)
8、c语言中存储区怎么划分?什么是作用域?
答:分区:分别是静态存储区,栈区,堆区,常量区,代码区
作用域:通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
9、堆栈溢出的原因有哪些?
答:堆空间溢出:申请动态内存太大
栈空间溢出:函数调用层次太深
10、不能做switch()参数的是?
答:实型变量(float,double,string),能做switch()参数的是:byte,char,short,int,long,bool,整数类型和枚举类型
11、如果局部变量与全局变量重名会出现什么?
答:函数体内局部变量会屏蔽全局变量,若要使用被屏蔽的全局变量,需要在全局变量前加上::(域运算符)
12、全局变量可不可以在定义在一个被多个C文件包含的头文件中?
答:不可以。在被多个c文件包含的头文件中定义变量会在编译时报错,提示重复定义(即使加static关键字过了编译,但是相当于多个源文件有多个同名的局部变量)
13、什么是野指针?
答:野指针就是指向一个已销毁的对象或者访问受限内存区域的指针
14、什么是断点调试?
答:断点是调试器设置源程序在执行过程中自动进入中断模式的一个标记。当程序运行到断点时,程序中断执行,进入调试状态。
15、字符数组的初始化?字符数组和字符串
答:字符数组的初始化有两种方式,用单个字符列表和用字符串常量;用常量字符串初始化数组时系统在最后一个字符后面加\0。
16、什么是回调函数?
答:回调函数即定义一个函数,然后把这个函数作为参数传入子程序中,由子程序在运行时通过函数指针来调用的函数。
17、const关键字的作用?
答:常变量:不能被修改的变量(局部常变量在编译时,全局常变量在运行时)
const指针:不能改变指向的指针变量
指向常量的指针:可以改变指向,但不能通过该指针修改对象
常成员函数:不能修改类的成员变量
对const的引用:对象可修改,但不能通过该引用修改对象
18、define和const的区别?
答:生效时间:define在预编译,const在编译和运行阶段
类型检查:define是字符替换,无类型检查;const有数据类型,有类型检查
存储方式:define定义的宏常量在内存中可以存在若干备份;const定义的只读变量在内存中只存在一份
19、默认构造函数的特点?
答:默认构造函数一个类只能有一个,由不带参数的构造函数,当类中没有显式定义任何构造函数时,编译器自动生成一个公有的默认构造函数。
(多个构造函数类似函数重载)
20、拷贝构造函数
答:本质上也是一种构造函数,当用一个对象创建另一个对象时调用,而不会调用类自带的构造函数。
复制构造函数的参数是引用或者是常量引用,不自己定义就会编译器生成默认复制构造函数,不是无参构造函数
起作用:参数放对象,初始化语句
对象间赋值不会导致赋值函数被调用
20、什么是命名空间?命令空间可以嵌套吗?
答:概念:命名空间是一种防止名字冲突的机制,分割了全局命名空间,其中每个命名空间是一个作用域
嵌套:命名空间可以嵌套,可以取别名
21、关于继承方式和可见性?
答:public继承方式:1.基类中所有public成员在派生类中为public属性;
2.基类中所有protected成员在派生类中为protected属性;
3.基类中所有private成员在派生类中不可访问。
protected继承方式:1.基类中的所有public成员在派生类中为protected属性;
2.基类中的所有protected成员在派生类中为protected属性;
3.基类中的所有private成员在派生类中仍然不可访问。
private继承方式:1.基类中的所有public成员在派生类中均为private属性;
2.基类中的所有protected成员在派生类中均为private属性;
3.基类中的所有private成员在派生类中均不可访问。
22、面向对象三大特性有哪些?如何理解?
答:封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。
继承:使用现有类的所有功能,并在不重写现有类的情况下对这些功能进行扩展。
多态:不同的对象对同一个消息产生不同的响应。静态多态即函数重载和运算符重载,动态多态用虚函数实现,允许将子类类型的指针赋值给父类类型的指针。
(抽象:抽象就是将一些事物的共性和相似点抽离出来,并将这些属性归为一个类)
23、请你说一说你理解的虚函数和多态?
答:多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定;动态多态是用虚函数机制实现的,在运行期间动态绑定。
虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。
当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。
使用了虚函数,会增加访问内存开销,降低效率。
24、c语言如何实现差错控制?
答:c语言中的差错控制通过条件判断语句实现,判断参数是否在正确的范围内
25、不用中间变量怎么交换两个数?
答:1.利用两数之和减去另一个数的方式
2.利用异或运算
(乘除不能碰见0,所以乘除不行)
26、自增运算符前置和后置,在无编译器优化的情况下,哪个效率更高?
答:自增运算符前置效率更高。因为前置运算符先将自身递增,然后返回自身;后置运算符先创建自身的一个副本,而后自身递增,然后返回副本。
27、程序怎么更有效率执行?
1、减少程序在核心态和用户态之间的切换
2、使用线程代替进程以减少系统资源的开销
3、使用 inline,避免函数调用的开销;
4、自己管理内存,避免内存分配的开销;
28、如果同时定义了两个函数,一个带const,一个不带,会有问题吗?
答:不会,这相当于函数的重载。
29、请你回答一下new/delete与malloc/free的区别是什么
答:首先,new/delete是C++的关键字,而malloc/free是C语言的库函数,后者使用必须指明申请内存空间的大小,对于类类型的对象,后者不会调用构造函数和析构函数
30、请你说说c语言中返回值的存储?
答:1.函数返回变量值(暂存于eax寄存器)
2.函数返回地址(暂存于eax寄存器)
31、请你说说C语言参数压栈顺序?为什么?
答:从右到左,是为了支持可变长参数形式。对于可变参函数,需要用format来确定参数个数,从右到左压栈,可以用栈顶指针+2得到format的地址
32、请你说一说重载和覆盖?
答:重载:两个函数名相同,但是参数列表不同(个数,类型),返回值类型没有要求,在同一作用域中
重写:子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数,这种情况是重写
33、请你来说一下C++中struct和class的区别?
答:在C++中,可以用struct和class定义类,都可以继承。区别在于:struct的默认继承权限和默认访问权限是public,而class的默认继承权限和默认访问权限是private。
34、请你来回答一下include头文件的顺序以及双引号””和尖括号<>的区别?
答:对于使用双引号包含的头文件,查找头文件的路径时优先查找当前头文件目录
对于使用尖括号包含的头文件,查找头文件的路径时优先查找编译器设置的头文件路径
35、请你来说一下什么时候会发生段错误?
答:段错误通常发生在访问非法内存地址的时候,具体来说分为以下几种情况:
使用野指针或试图修改常量区的内容
36、alloc malloc calloc realloc的区别?
答:alloc向栈申请空间
malloc向堆申请空间,参数为空间大小
calloc和malloc类似,参数为元素数目和大小
realloc是给一个已经分配了地址的指针重新分配空间
37、c语言函数传输传递的三种方式?
答:值传递,指针传递,引用传递
38、什么是内联函数?
答:编译器处理内联函数的调用语句时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的指令。内联函数一般定义在头文件,便于多个源文件编译替换
(如果函数语句少,调用频繁,调用函数的开销就相对比较大)
39、什么是浅拷贝?什么是深拷贝?
答:缺省的拷贝构造函数为浅拷贝,两个对象共用一个存储空间
深拷贝就是自己定义拷贝构造函数,需要新建一个内存空间保存数据
(注:当一个对象的成员函数中有某种需要分配的资源,为了防止该资源被多次析构,则需要自定义拷贝构造函数)
40、什么是内存泄漏?
答:内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
41、源码到可执行文件的过程?
答:预处理 编译 汇编 链接
42、已定义的函数有返回值,函数调用可以作为一个函数的实参,但是不能作为形参,为什么?
答:返回值存在eax寄存器中, 没有地址, 只有值,不能作为形参,但可以作为实参。
43、c++中不会被继承的部分?
答:基类的构造函数、析构函数和拷贝构造函数
基类的重载运算符
基类的友元函数
44、什么是抽象类?有什么特点?
答:包含纯虚函数的类就是抽象类。抽象类不能被用于实例化对象,它只能作为接口使用。
45、c++不能被重载的运算符有哪些?
答:成员访问运算符.
成员指针访问运算符.*
域运算符::
sizeof运算符sizeof
条件运算符?:
46、栈上的局部对象调用时机?
答:构造函数:定义对象时调用,用来初始化一个对象
析构函数:对象出作用域时调用
47、全局对象的构造析构函数调用时机?
答:构造函数:进入main函数之前
析构函数:main函数返回之后
48、什么是this指针?
答:this指针是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址
49、类定义的对象和类的关系?
答:类里面的数据成员是私有的,各自有各自的地址,成员函数是公有的,同一个类的对象,其成员函数地址是一样的
50、函数重载的条件是什么?函数重载的调用规则?
答:重载条件:函数名必须相同,作用域必须相同,函数参数个数不同或者类型不同或者顺序不同,返回值不同不能算函数重载
调用规则:首先根据函数名找到对应的函数,作为候选函数,再在候选函数中找到可以匹配的函数,匹配函数个数=0,报错,=1则使用该函数,>1则二义性
51、面向过程和面向对象的区别?
答:面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一一实现,使用的时候依次调用
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
52、volatile关键字的作用是什么?
答:volatile修饰的变量防止编译器的优化,且要求每次直接读值。