1. struct和union的区别?
答:①联合体所有的成员都共享一块内存,修改联合体的任一成员的数据就会覆盖到其他成员的数据;
②结构体的成员变量都有独立的内存空间,且结构体的成员数据之间是不影响的
2. struct和class的区别?
答:①访问权限不同:class默认是私有的private,struct默认是公共的public
②继承权限不同:class默认是私有的private,struct默认是公共的public
③class可以用于定义模板,而struct不能
3. 指针和地址偏移问题
int main(){
unsigned char *p1;
unsigned long *p2;
p1 = (unsigned char *)0x801000;
p2 = (unsigned long *)0x810000;
//p1+5偏移sizeof(unsigned char)*5 = 1*5
printf("p1+5 = %p\n",p1+5); //答案:0x801005
//p1+5偏移sizeof(unsigned long)*5=8*5=40(十进制)= 28(十六进制)
printf("p2+5 = %p\n",p2+5); //答案:0x810028
return 0;
}
4. 宏定义的陷阱 – “无脑替换”
#define CUBE(x) x*x*x
int main(){
int a = 3;
printf("%d\n", CUBE(a)); //CUBE(a) = a*a*a = 27
//CUBE(a+1) = a+1*a+1*a+1 = a+a+a+1 = 10
printf("%d\n", CUBE(a+1));
return 0;
}
5. 大小端字节序判断
- 大端字节序:高地址存放数据的低位(网络字节序)
- 小端字节序:高地址存放数据的高位(X86 PC)
union Test{
short a;
char b[2];
};
int main(){
union Test test;
test.a = 0x1234;
if(test.b[0] == 0x12){ //低地址放高位
printf("Big Endian\n");
}
if(test.b[0] == 0x34){ //低地址放低位
printf("Small Endian\n");
}
return 0;
}
6.【面试真题】
- 在X86架构的PC机上,下列程序输出结果是( A )
7. 枚举enum的赋值规则
8. 左值(lvalue)和右值(rvalue)的区别?
答:①左值:表示一个可被标识和修改的内存位置,可以出现在=左边的变量,其值可以改变,存储在内存中具有持久性。(典型的左值包括变量、数组元素和通过引用或指针访问的对象)
②右值:不能被赋值的常量、表达式,特点是可读。一般是临时的中间值或者常量。
③通常左值可以做右值,右值不能做左值(如:i++ = 5的写法是错误的)
注意:数组名是常量,不能被赋值,也就是数组名是右值。
(当定义char array[10] = “hello”时,array++和array=array+1都是错误的写法)
(区别定义char *array = “hello”时,array++和array=array+1的写法是允许的)
9. ++a和a++的区别?
- 如果有表达式 a = i++ ;它等价于 a = i;i = i + 1(先赋值再自增,右值)
- 如果有表达式 a = ++i;它等价于i = i + 1;a = i(先自增再赋值,左值)
10. 在1G内存的PC中能否malloc(1.2G)?为什么?
答:可能可以。因为malloc是向进程申请虚拟内存,与物理地址空间没有直接关系。
11. 数组的负数下标
【面试真题】 写出下面程序的输出结果:0 1 2 3 4 5
12. 判断有符号、无符号整数
【面试真题】 写出判断一个整数是否是无符号整数的宏定义:
13. select、poll和epoll的区别?
答:①select相比于poll和epoll,支持跨平台可移植性好;但是select的实现是依赖轮询机制,且每次调用都需要在用户态和内核态之间复制拷贝所有文件描述符,因此效率比较差,并且监听的最大文件描述符数量也有限制,一般是1024个。
②poll在select的基础上,有了一定的改进和优化;但是底层实现机制和select一样,在效率上并没有大的提升。
③epoll相比于前面select和poll,可以说是最高效最常用的。它是基于内核事件驱动机制实现对事件的监听,底层通过红黑树和链表来存储监听的文件描述符和事件,当监听到事件发生,以消息通知的机制处理对应的文件描述符,避免了前面select和poll轮询机制的缺点,提高了效率,且没有文件描述符数量的限制。
14. 面向对象三大特征
继承、封装、多态