西邮Linux兴趣小组2018年面试题
数组可以看作是一行连续的数据,二维数组在概念上是二维的,但在内存中是连续存放的.
- 对于一维数组,1[array] == array[1]
- 对于二维数组,(i)[array][j]==arry[i][j]
-
a是一个二维数组,占用32的内存空间,而int为4个字节,所以输出sizeof(a)=43*2=24;
-
a[1][1]指数组中第一行第一列的元素,为int型,所以输出4 8;
-
第3个printf中的sizeof测的实际上是指针类型,在64位机下为8个字节;转义字符以反斜’\‘开头,后面跟一个字符或一个八进制或十六进制数表示。所以题目中的’\0101’表示的是’65’,所以输出8,6.
strlen和sizeof的区别:
- strlen是一个函数,而sizeof是一个单目运算符;
- strlen用来指定字符串长度,不包括空字符’\0’.
- strlen只能用cahr*做参数,且必须以’\0’结尾,即strlen只能用来计算字符串长度.
对 sizeof 而言,因为缓冲区已经用已知字符串进行了初始化,其长度是固定的,所以 sizeof 在编译时计算缓冲区的长度.也正是由于在编译时计算,因此 sizeof 不能用来返回动态分配的内存空间的大小.
sizeof使用的注意事项
- 对于直接的调用sizeof,如果是数组首地址,sizeof会输出数组所占地址空间的大小(字节为单位)。如果是一个指针的话,则输出在该系统中地址的字节宽度,即(位宽/8).
int *a;
char b[30];
char *c;
printf("%d, %d, d\n", sizeof(a), sizeof(b),sizeof(c));
输出4,30,4
- 如果是通过函数传递过来的地址,那么sizeof会把数组首地址和指针无差别当成是地址.
void test_sizeof_addr(char *a)
{
printf("%d\n", sizeof(a));
}
void test_sizeof_array(char a[])
{
printf("%d\n", sizeof(a));
}
int main()
{
char b[30];
test_sizeof_addr(b);
test_sizeof_array(b);
return 0;
}
输出4 4
输出 a=2018,b=1
a=2019,b=2
a=2020,b=3
static
- static全局变量和普通全局变量区别:
static全局变量和普通全局变量存储方式都为静态存储方式,区别在于各自的作用域,普通全局变量的作用域是整个源程序,,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都有效,而静态全局变量则限制了作用域,只在定义该变量的源文件中有效. - static局部变量和普通局部变量区别:
static局部变量和普通局部变量的存储方式即生存期不同,static局部变量具有全局的生存期, 只初始化一次, 离开函数后仍然存在, 具有函数内的局部作用域,是特殊的全局变量. - static函数和普通函数区别:
static函数与普通函数作用域不同,仅在本文件.只在当前源文件中使用的函数应该说明为内部函数即static修饰的函数,内部函数应该在当前源文件中说明和定义.对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.
C源程序到可执行文件的四个过程
-
预处理:预编译器执行.文件后缀为.i;
-
编译:编译器执行.进行一系列词法分析、语法分析、语义分析及优化后,生成相应的汇编代码文件,文件后缀为.s;
-
汇编:将汇编代码转变成机器可以执行的指令.文件后缀为.o;
-
链接:链接器执行。把.o文件中的各函数(段)按照一定规则累积在一起,形成可执行文件,文件后缀为.out.
const详解
- int const a等价于int const b
- char *const p表示指针变量p中的地址不可被修改
- const char *p表示指针p所指向的内存空间的内容不可被修改
- const char *const p表示指针变量和指针指向的内存空间都不可被修改
故(1)(4)是错误的
0x7fffc9cb3950
0x7fffc9cb3954
0x7fffc9cb3950
0x7fffc9cb3964
a表示数组的首地址
&a表示数组首元素的地址
a+1表示数组首地址加上一个元素所占的地址大小,这里int是4个字节,所以加上1x4.
&a+1表示加上整个数组的大小,这里数组尺寸是5,所以+1代表的是地址加上4x5.
- argc和argv是main函数的形式参数。这两个形式参数的类型是系统规定的。如果main函数要带参数,就是这两个类型的参数;否则main函数就没有参数。
- main函数的返回值,用于说明程序的退出状态。如果返回0,则代表程序正常退出;返回其他数字的含义则由系统决定,通常,返回非零代表程序异常退出。
f(2018)=7
按位与(&):1&1==1,1&0==0,0&0==0
函数的作用为判断一个数的二进制数中1的个数
涉及大小端问题 反向存储,正向输出
所以数据的储存方式为
0000 0000
0000 0000
0000 0000
0000 0001
所以最终输出结果为1
7
XiyouLinux YEAR
XiyouLinux 2018
先将实参1+2,3带入形参x,y中,得到1+2*3=7
再将YEAR作为字符串带入形参x中,’#‘符号代表将两个字符串连接起来,所以得到XiyouLinux YEAR
然后又代入LEVELTWO中,因为定义了YEAR为2108,所以输出 XiyouLinux 2018
输出16 24
一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。
结构体内存空间的计算:
-
一、当结构体成员是基本类型变量时
总体遵循两个原则:1. 数据对齐原则:内存按结构体成员的先后顺序排列,当排到该成员时,其前面已摆放的空间大小必须是该成员类型大小的整数倍,如果不够则补齐,依次向后类推; 2. 最终的整体空间是占用空间最大的成员类型所占字节的整数倍。
-
二、当结构体成员是另外一个结构体时
将本结构体称为父结构体,把成员结构体称为子结构体1. 数据对齐原则:父结构体内存按结构体成员的先后顺序排列,当排到子结构体成员时,其前面已摆放的空间大小必须是该子结构体中最大类型大小的整数倍,如果 不够则补齐,依次类推; 2. 整体空间是子结构体与父结构体中占用空间最大的成员类型所占字节的整数倍。
-
三、结构体成员是数组类型时
只要不把数组看作数组,而把它看成一个个类型相同的成员变量序列!然后用前面的计算方法计算即可。
所以结构体icd中整体结构应该为4+4+8=16
结构体cdi中整体结构应该为8+8+4+4=24
表示以二进制的形式写入文件,如果文件存在,则清空文件内容,如果不存在,则新建一个文件"Linux.txt",此时Linux.txt为空;
定义了一个长整型变量a,以十六进制存储数据;
fwrite()函数的功能是把&a所指向的数据写入到fp中,写入的每个元素的大小为sizeof(a),将数据转换为字符串并写入到Linux.txt中,内容则为Linux.