44.变量的声明和定义有什么区别
??为变量分配地址和存储空间的称为定义,不分配地址的称为声明。 ??一个变量可以在多个地方声明,但是只在一个地方定义。 ??加入 extern 修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。 (PS:很多时候一个变量,只是声明不分配内存空间,直到具体使用时才初始化,分配内存空间,如外部变量。)
45.sizeof 和 strlen 的区别
??sizeof 和 strlen 有以下区别:
- sizeof 是一个操作符,strlen 是库函数。
- sizeof 的参数可以是数据的类型,也可以是变量,而 strlen 只能以结尾为‘\0‘的字符串作参数。
- 编译器在编译时就计算出了 sizeof 的结果。而 strlen 函数必须在运行时才能计算出来。并且 sizeof计算的是数据类型占内存的大小,而 strlen 计算的是字符串实际的长度。
- 数组做 sizeof 的参数不退化,传递给 strlen 就退化为指针了。
46.简述 strcpy、sprintf 与 memcpy 的区别
??三者主要有以下不同之处:
- 操作对象不同,strcpy 的两个操作对象均为字符串,sprintf 的操作源对象可以是多种数据类型,目的操作对象是字符串,memcpy 的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。
- 执行效率不同,memcpy 最高,strcpy 次之,sprintf 的效率最低。
- 实现功能不同,strcpy 主要实现字符串变量间的拷贝,sprintf 主要实现其他数据类型格式到字符串的转化,memcpy 主要是内存块间的拷贝。
(PS:strcpy、sprintf 与 memcpy 都可以实现拷贝的功能,但是针对的对象不同,根据实际需求,来选择合适的函数实现拷贝功能。)
47.链表和数组有什么区别
??数组和链表有以下几点不同:
- 存储形式:数组是一块连续的空间,声明时就要确定长度。链表是一块可不连续的动态空间,长度可变,每个结点要保存相邻结点指针。
- 数据查找:数组的线性查找速度快,查找操作直接使用偏移地址。链表需要按顺序检索结点,效率低。
- 数据插入或删除:链表可以快速插入和删除结点,而数组则可能需要大量数据移动。
- 越界问题:链表不存在越界问题,数组有越界问题。
(PS:在选择数组或链表数据结构时,一定要根据实际需要进行选择。数组便于查询,链表便于插入删除。数组节省空间但是长度固定,链表虽然变长但是占了更多的存储空间。)
48.typedef 和 define 有什么区别
- 用法不同:typedef 用来定义一种数据类型的别名,增强程序的可读性。define 主要用来定义常量,以及书写复杂使用频繁的宏。
- 执行时间不同:typedef 是编译过程的一部分,有类型检查的功能。define 是宏定义,是预编译的部分,其发生在编译之前,只是简单的进行字符串的替换,不进行类型的检查。
- 作用域不同:typedef 有作用域限定。define 不受作用域约束,只要是在 define 声明后的引用都是正确的。
- 对指针的操作不同:typedef 和 define 定义的指针时有很大的区别。
注意:typedef 定义是语句,因为句尾要加上分号。而 define 不是语句,千万不能在句尾加分号。
49.局部变量能否和全局变量重名
??能,局部会屏蔽全局。要用全局变量,需要使用"::"。
50.如何引用一个已经定义过的全局变量
??可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错;如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在链接期间报错。
51.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么
??可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时链接不会出错。
52.const与#define相比有何优点
- const 常量有数据类型,而宏常量没有数据类型。编译器可以对const修饰的数据进行类型安全检查。而对宏常量只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。
- 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。
53.几种内存分配方式以及它们的区别
- 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
- 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令。
- 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
54.有哪几种情况只能用初始化列表而不能使用赋值
??当类中含有const成员变量和引用成员变量时,基类的构造函数都需要初始化表。
55.堆栈溢出一般是由什么原因导致的
56.C++中的空类,默认产生的类成员函数
class
{
public:
Empty();
Empty(const Empty&);
~Empty();
Empty& operator=(const Empty&);
Empty* operator&();
const Empty* operator&() const;
};
57.进程间
- 进程间通信的方式有 :共享内存, 管道(有名管道/无名管道),Socket ,消息队列 ,信号,信号量,内存映射等。
- 进程死锁的原因:资源竞争及进程推进顺序非法。
- 死锁的四个必要条件:互斥,请求保持,不可剥夺,环路。
58.数组和链表的区别?
- 数组的数据是顺序存储的,存储大小固定。
- 链表的数据可以随机存储,存储大小可以动态的改变。
59.关于windows程序
??1.windows应用程序的类型:控制台程序、窗口程序、库程序(静态/动态)
??2.win32程序的执行机制:win32窗口程序是采用事件驱动方式执行,也就是消息机制。(PS:程序的执行机制分为过程驱动和事件驱动)
??3.Windows中消息可以分为几类?
- 系统消息——由系统定义好的消息,可以在程序中直接使用。
- 用户自定义消息——由用户自己定义,满足用户自己的需求。由用户自己发出消息,并响应处理
- 应用程序消息——程序之间通讯时使用的消息。
- 系统注册消息——在系统注册并生成相应消息,然后可以在各个程序中使用这个消息。
??4.消息队列的类型
- 系统消息队列——由系统维护的消息队列。存放系统产生的消息,例如鼠标、键盘等。
- 程序消息队列——属于每一个应用程序(线程)的消息队列。由应用程序(线程)维护。
|