问题1:100年有多少秒(忽略闰平年)?
#define SEC (3600*24*365*100u)
问题2:指针与数组名区别
数组名就是数组的首地址,数组名与数组的内存之间是映射关系,相当于一个特殊的指针,是常量,是不能修改的
数组作为函数参数时会蜕变成指针,所以长度才丢失,因此需要额外传递长度参数
所以数组名可以解引用,如果指针指向数组,指针可以使用中括号来使用,也就是指针也可以当作数组使用
数组名与内存时映射关系,指针与内存是指向关系
int arr[] <=> int* arr
arr[i] == *(arr+i)
&arr[i] == arr+i
问题3:堆内存与栈内存的区别
堆内存:是进程的一个内存段(text\data\bss\heap\stack),由程序员手动管理的。
优点:足够大
缺点:使用比较麻烦
栈内存:由系统管理、会随着函数的调用自动分配内存、函数的结束释放内存。
优点:使用方便
缺点:大小有限,超过会段错误
问题4:堆内存越界的后果
超过33页产生段错误
破坏了malloc的维护信息,再次使用malloc/free会报错
脏数据
易产生内存泄漏和内存碎片
问题5:什么是内存泄漏?如何定位内存泄漏的?
由于业务逻辑出错、粗心大意导致使用完毕后的堆内存没有被释放,当再次使用时又重新申请,有没有释放,长时间积累导致可用的内存越来越少,系统会越来越慢甚至崩溃,这叫做内存泄漏
1、windows查看任务管理器,Linux通过ps命令,定位泄漏的进程
2、使用mtrace内存分析工具,检查是否有没释放的堆内存
3、封装malloc、free,记录malloc、free使用情况到日志
问题6:
已经释放但也无法继续使用的内存叫做内存碎片,是由于申请和释放的时间不协调导致的,是无法避免的只能尽量减少
1、尽量使用栈内存
2、不要频繁地申请和释放内存
3、尽量申请大块内存自己管理
问题7:typedef和宏的比较
如果是普通类型,它们的功能上没有区别
#define INT int
typedef int INT
如果是指针类型
#define INTP int*
INTP p1,p2,p3;//p1是指针,p2p3是int类型变量
typedef int* INTP;
INTP p1,p2,p3;//p1p2p3是指针
问题8:宏函数与普通函数的区别
在定义上:
函数:是一段具有某项功能的代码,会被编译成二进制指令存储在代码段中,函数名就是它的首地址,有独立的命名空间、栈空间
宏函数:不是真正的函数,只是代码替换,用起来像函数
1、函数有返回值,宏函数为运算结果(式子)无返回值
2、函数要类型检查,宏函数通用不会进行类型检查
3、函数进行类型检查更安全,相比较之下宏函数较危险
4、函数的数据经过入栈和出栈,宏函数只是替换
5、函数在代码中要进行跳转运行速度慢,宏函数直接进行替换速度快
6、函数的代码为跳转,宏函数替换产生冗余