您的位置:首页 > 编程语言 > C语言/C++

c++ 面经(1) ------ 面经之基础知识

2018-03-04 16:43 204 查看
自己写的面经,也是找了一段时间,现在总结出来遇见的以及可能遇见的。还有些经常会被问到的。都总结出来以供大家参考。
基础知识
1.常用的类型范围
int   -2147483648 ~ +2147483647   (4 Bytes)
unsigned int         0 ~ 4294967295    (4 Bytes)

char  -128 ~ +127    (1 Bytes)
short  -32767 ~ +32768 (2 Bytes)
unsigned short     0 ~ 65536        (2 Bytes)

long == int

long long   -9223372036854775808 ~ +9223372036854775807    (8 Bytes)
double   1.7 * 10^308        (8 Bytes)
float小数点前后加起来有效数字只有6位
double 小数点后面有效数字16位

2.计算机 -大端小端问题
大端小端是高地地址问题,大端是高地址在前,小端是低地址在前。跟cpu有关。
我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。

其实大端小端是个多字节排序的问题。
3.sizeof strlen问题
sizeof() 是一个判断数据类型或者表达式长度的运算符

sizeoof(char*)  指的是所占的字节数 ----注意32、64位系统
strlen() --- 计算的是字符串的长度

4.堆和栈、堆和栈访问速度谁快、new和malloc的区别(new比malloc多些什么,在申请或者释放多了那些)
堆和栈:

的内存增长方向是自低向高处的增长。低 ->高 增长。
的内存增长方向是自高向低增长。高 ->低 增长。----- 因为栈内存都是系统分配的可以理解为分配的空间是连续的。
在malloc多次申请时,malloc会内存不同位置申请连续的空间,所以容易造成内存碎片化。
堆和栈在访问速度上,栈更快。原因如下:
(1).分配和释放,堆在分配和释放都要调用函数(malloc,free),去内存寻找到足够大小的空间。这些栈都不需要。
(2).访问时间,正常访问堆时需要两次操作,第一次获取指针,第二步取相应数据。而栈只需要访问一次就可以取到内容。
(3).栈有专门寄存器,压栈和出栈很快,而堆需要os动态调整。
分配方式上,堆是动态分配的,栈是编译器完成的。
new和malloc的区别(new比malloc多些什么,在申请或者释放多了那些):

new和malloc的区别是C/C++一道经典的面试题 ---- 需要注意

(1).属性:
new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。

(2).参数:
使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸

(3).返回类型:
new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

(4).分配失败:
new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

(5).自定义类型:
new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。

malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

(6).重载:
C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。

(7).内存区域:
new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。
(8) C++内存管理方式:
堆、栈、自由存储区、全局\\静态存储区、常量存储区

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

自由存储区//堆:free 和malloc用在堆上,有些编译器中new和delete用的是free和malloc去申请的内存在堆上,但是如果通过重载操作符,改变其他内存实现自由存储,例如全局变量做的对象池,这时自由存储区就区别于堆了。堆与自由存储区并不完全等价

5.const的应用
指针常量 const int *p: p是一个指针,指向const int,表示的意义就是不能通过p来修改p指向的值,而p本身所指向的地址是可以修改的。(此处也可以写成int const *p是一样的)
常量指针 int* const p: 表示p本身是一个const,所以p所指的地址不会变,但是地址里的值是可以修改的。
const int *x  const在*前面,该数据不能改变

int* const y const在地址前面,该地址不能变化

6.常用的c函数和头文件,memcpy、memcmp、strcmp、strncmp、strcpy、strncpy
memcpy:

memcpy    ==> c 语言 #include <string.h>

                ==> c++ #include<cstring>

memcmp:

memcmp(const void *buf1, const void *buf2, unsigned int count);

比较内存区域buf1和buf2的前count个字节。
返回值:

当buf1<buf2时,返回值<0当buf1=buf2时,返回值=0当buf1>buf2时,返回值>0==> 头文件 #include<string.h>
strcmp:
头文件 #include<string.h>
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1<str2,则返回负数;
若str1>str2,则返回正数
strncmp:
头文件 #include<string.h>
int strncmp ( const char * str1, const char * str2, size_t n );

比较s1和s2字符串,如果字符串s1与s2的前size个字符相同,函数返回值为0。

strcpy/strncpy:

头文件 #include<string.h>

strcpy 计算长度等等字符串处理,都是自动到’\0’字符。
strncpy  若a未初始化,未拷贝赋值的后半a全部赋值0,即空字符’\0’。若a已初始化,未拷贝赋值的后半a依然保持原样。

7. c和c++ 头文件的区别
#include <stdio.h> c头文件
#inlcude <cstdio> c++头文件

8. 关键字 static、extern、inline、volatile
static:

static 结果保存在全局数据区(静态区)
static 静态局部变量,函数结束后其中的变量并没有消失,而是在整个程序结束后才会消失。
extern:
(1) extern 如果和c连接在一起用。如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的
(2) extern 不和c一起用,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块活其他模块中使用
inline:
为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间
在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足而导致程序出错的问题
优点:使用内联函数,效率高,运行快。
使用条件:
内联编译的建议性由编译器决定。
逻辑简单调用频繁的函数,建议使用内联函数。
递归函数无法使用内联函数。

volatile:
嵌入式编程应用:
(1) 告诉compiler不能做任何优化

比如要往某一地址送两指令:
int *ip =...; //设备地址
*ip = 1; //第一个指令
*ip = 2; //第二个指令
以上程序compiler可能做优化而成:
int *ip = ...;
*ip = 2;
结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意:
volatile int *ip = ...;
*ip = 1;
*ip = 2;
即使你要compiler做优化,它也不会把两次赋值语句间化为最后一句,它只能做其它的优化。这对device driver程序员很有用。
(2)表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。
易变性。所谓的易变性,在汇编层面反映出来,就是两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是重新从内存中读取。如:
volatile char a;
a=0;
while(!a)
{
//do some things;
}
doother();
如果没有 volatile,doother()不会被执行
此例转自:http://blog.csdn.net/k346k346/article/details/46941497这个对于volatile说的很详细很好推荐 转载:http://blog.csdn.net/c359719435/article/details/51490060
设计出来的C/C++ Volatile关键词,所含有的特性,三个特性:易变性;不可优化性;顺序性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试 c BAT