编程语言C/C++(三)
编程语言C/C++(三)
1. 结构体内存对齐问题?
- 按序存储,装得下尽量装,装不下换一行。
- 如果最大的基本元素小于等于机器位宽,按照最大基本元素大小对齐,
否则按照机器字长对齐。
2. static作用是什么?在C和C++中有何区别?
- static可以修饰局部变量(静态局部变量)、全局变量(静态全局
变量)和函数,被修饰的变量存储位置在静态区。对于静态局变量,相
对于一般局部变量其生命周期长,直到程序运行结束而非函数调用结束,
且只在第一次被调用时定义;对于静态全局变量,相对于全局变量其可
见范围被缩小,只能在本文件中可见;修饰函数时作用和修饰全局变量
相同,都是为了限定访问域。
- C++的static除了上述两种用途,还可以修饰类成员(静态成员变
量和静态成员函数),静态成员变量和静态成员函数不属于任何一个对
象,是所有类实例所共有。
- static的数据记忆性可以满足函数在不同调用期的通信,也可以满
足同一个类的多个实例间的通信。
- 未初始化时,static变量默认值为0。
3. malloc和new的区别?
- malloc和free是标准库函数,支持覆盖;new和delete是运算符,
并且支持重载。
- malloc仅仅分配内存空间,free仅仅回收空间,不具备调用构造函
数和析构函数功能,用malloc分配空间存储类的对象存在风险;new和
delete除了分配回收功能外,还会调用构造函数和析构函数。
- malloc和free返回的是void类型指针(必须进行类型转换),new
和delete返回的是具体类型指针。
4. 指针和引用区别?
- 引用只是别名,不占用具体存储空间,只有声明没有定义;指针是具
体变量,需要占用存储空间。
- 引用在声明时必须初始化为另一变量,一旦出现必须为typename
refname &varname形式;指针声明和定义可以分开,可以先只声明指
针变量而不初始化,等用到时再指向具体变量。
- 引用一旦初始化之后就不可以再改变(变量可以被引用为多次,但引
用只能作为一个变量引用);指针变量可以重新指向别的变量。
- 不存在指向空值的引用,必须有具体实体;但是存在指向空值的指针。
- 不能建立数组的引用。
5. 宏定义和函数有何区别?
- 宏在编译时完成替换,之后被替换的文本参与编译,相当于直接插入了
代码,运行时不存在函数调用,执行起来更快;函数调用在运行时需要
跳转到具体调用函数。
- 宏函数属于在结构中插入代码,没有返回值;函数调用具有返回值。
- 宏函数参数没有类型,不进行类型检查;函数参数具有类型,需要检
查类型。
- 宏函数不要在最后加分号。
6. 宏定义和const区别?
- 宏替换发生在编译阶段之前,属于文本插入替换;const作用发生于
编译过程中。
- 宏不检查类型;const会检查数据类型。
- 宏定义的数据没有分配内存空间,只是插入替换掉;const定义的变
量只是值不能改变,但要分配内存空间。
7. 宏定义和typedef区别?
- 宏主要用于定义常量及书写复杂的内容;typedef主要用于定义类型
别名。
- 宏替换发生在编译阶段之前,属于文本插入替换;typedef是编译的
一部分。
- 宏不检查类型;typedef会检查数据类型。
- 宏不是语句,不在在最后加分号;typedef是语句,要加分号标识结
束。
- 注意对指针的操作,typedef char * p_char和
#define p_char char *区别巨大。
8. 宏定义和内联函数(inline)区别?
- 在使用时,宏只做简单字符串替换(编译前)。而内联函数可以进行
参数类型检查(编译时),且具有返回值。
- 内联函数本身是函数,强调函数特性,具有重载等功能。
- 内联函数可以作为某个类的成员函数,这样可以使用类的保护成员和
私有成员。而当一个表达式涉及到类保护成员或私有成员时,宏就不能
实现了。
9. volatile有什么作用?
- volatile定义变量的值是易变的,每次用到这个变量的值的时候都
要去重新读取这个变量的值,而不是读寄存器内的备份。
- 多线程中被几个任务共享的变量需要定义为volatile类型。
10. a和&a有什么区别?
假设数组int a[10];
int (*p)[10] = &a;
- a是数组名,是数组首元素地址,+1表示地址值加上一个int类型的大
小,如果a的值是0x00000001,加1操作后变为0x00000005。
*(a + 1) = a[1]。
- &a是数组的指针,其类型为int (*)[10](就是前面提到的数组指
针),其加1时,系统会认为是数组首地址加上整个数组的偏移(10个
int型变量),值为数组a尾元素后一个元素的地址。
- 若(int *)p ,此时输出 *p时,其值为a[0]的值,因为被转为
int *类型,解引用时按照int类型大小来读龋
11. 数组名和指针(这里为指向数组首元素的指针)区别?
- 二者均可通过增减偏移量来访问数组中的元素。
- 数组名不是真正意义上的指针,它是一种数据结构,可以理解为指针
常量,所以数组名没有自增、自减等操作。
- 当数组名当做形参传递给调用函数后,就失去了原有特性,退化成一
般指针,多了自增、自减操作,但sizeof运算符不能再得到原数组的
大小了。