整理一下最近遇到的笔试题,希望能被offer砸死。
第一题 int **a[2][4]在32位的机器上占用多少内存?
这定义了一个2*4的指针数组,每个指针的大小是4字节,所以总共占用了 2*4*4=32字节。int* 是指向数组的指针,int**是指向指针的指针,所以都是4字节。
第二题 #ifdef #if defined #if的区别
1 |
|
这段代码的输出是多少?
答案是count=7
#ifdef和#if defined判断是否宏定义过,区别是#ifdef只能判断单个宏是否定义过,#if defined可以写一些复杂的语法,比如
1
#if后面接表达式,表达式为真,编译器就会将后面的代码编译进去。
- 最后强调一点,这些宏定义都是决定代码是否会被编译,不是执行。
第三题 Union
1 | int main(){ |
运行后:test.a=1,test.b.b不确定,test.c=1;
Union的所有成员共用一个内存空间,内存空间以size最大的成员变量为准,所有成员从低地址开始对齐。一次只能访问一个成员变量,在对某个成员变量修改时也会改变其他成员变量的值,但当size不同时,只会覆盖相对应的内存部分。
在本题中,test.b.a的值修改后,test.a、test.c与其内存地址相同,也会被覆盖,test.b.b不会被修改,没有赋初值,所以是不确定。
大端模式和小端模式
- 大端模式(Big endian):数据的高字节存储在低地址中。
- 小端模式(Little endian):数据的低字节存储在低地址中。
union中的成员变量都是从低地址开始对齐的,所以,在不同的CPU下会有不同的结果,可以由union来判断CPU类型,看下面的例子:
1 | int main(){ |
char占1字节,int占4字节,由低地址开始对齐,每个地址存放一个字节(8位),在一个字节中的数是固定的,比如地址0x00存放的是01而不是10,与大小端无关。而int型占了4字节,如果是在小端模式下,低位地址存的是数据低位,test.x数据从高位到低位为04030201;在大端模式下,低位地址存的是数据高位,test.x为01020304,注意这个数是十六进制的。根据这个值就可以判断CPU是什么模式的了。一般的x86架构都是小端模式。
| 地址 | 0x00 | 0x01 | 0x02 | 0x03 |
|---|---|---|---|---|
| test.s | 01 | 02 | 03 | 04 |
主机序和网络序
- 主机序:不同的CPU有不同的字节序类型,即整数在内存中保存的顺序,一般有两种,就是之前说的大端模式与小端模式。
- 网络序:TCP/IP中定义的数据表示格式,保证数据在不同CPU类型的主机之间传输时能被正确解释。网络字节序采用大端模式。在数据传输时会进行主机序与网络序之间的转换,保证数据的正确性。
第四题 JavaScript 变量作用域
1 | var s = "global"; |
运行结果为:
undefined
local
Javascript中没有块级作用域,只有函数作用域,var声明的变量都是局部变量,变量在声明它的函数体内是有定义的。第一句的console.log(s)在s未声明就使用了,这时s是未定义的,外面定义的变量并不能作用到函数内部。
第五题 sizeof strlen
1 | int main(){ |
运行结果为:3 10
- sizeof 是运算符,其值在编译时就计算好了,获得能容纳实现所建立的最大对象的字节大小。
- strlen 是函数,是在运行时计算的,返回字符串的长度,从第一个地址开始遍历,直到遇到字符串的结束符’\0’。