对于面试过程中一些小知识的总结
1.对于sizeof的理解
sizeof()不是函数,而是一个关键字,不可扩展。sizeof()的结果类型为size_t
#include<stdio.h>
int main(void) {
int t = 2;
printf("%lu\n",sizeof t);
return 0;
}
编译通过了,说明语法正确
2.函数指针和指针函数
函数指针,指针函数即返回指针的函数
类型 *函数名称(参数)
后缀运算符括号“()”表示这是一个函数,其前缀运算符星号“*”表示此函数为指针型函数,其函数值为指针,即它带回来的值的类型为指针,当调用这个函数后,将得到一个“指向返回值为…的指针(地址),“类型名”表示函数返回的指针指向的类型”
指针函数,指向函数的指针
类型 (*名称(参数));
通过括号强行将名称首先与“*”结合,也就意味着,名称是一个指针,接着与后面的“()”结合,说明该指针指向的是一个函数,然后再与前面的类型结合,也就是该函数的返回值类型。由此可见,名称是一个指向以开始类型为返回值函数的指针
面试题是用用函数指针作为指针函数的返回值
size_t (*p(char *str))(size_t a) {
printf("%s\n",str);
return q;
}
*p(char *str)中的p(char *str)看成一个整体,一个指向函数的指针,返回的q正好是一个函数名称,当做
sizeof_t q(size_t)
3.
stdout, stdin, stderr的中文名字分别是标准输出,标准输入和标准错误。
在Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据流,也就是题目中所提到的这三个。那么什么是数据流呢(stream)?我们知道,一个程序要运行,需要有输入、输出,如果出错,还要能表现出自身的错误。这是就要从某个地方读入数据、将数据输出到某个地方,这就够成了数据流。
因此,一个进程初期所拥有的这么三个数据流,就分别是标准输出、标准输入和标准错误,分别用stdout, stdin, stderr来表示。
int main(){
fprintf(stdout,"Hello ");
fprintf(stderr,"World!");
return 0;
}
最后输出 World!Hello
在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行或者buffer满的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出,举例来说就是printf(stdout, “xxxx”) 和 printf(stdout, “xxxx\n”),前者会憋住,直到遇到新行才会一起输出。而printf(stderr, “xxxxx”),不管有没有\n,都输出。
4.
#include <stdio.h>
#include<string.h>
struct node{
char a;
short b;
int c;
};
int main(void) {
struct node s;
memset(&s, 0, sizeof(struct node));
s.a = 3;
s.b = 5;
s.c = 7;
struct node *pt = &s;
printf("%x\n",*(int *)pt);
printf("%llx\n",*(long long *)pt);
return 0;
}
对于小端(也就是上图的结果),我们可以理解为低字节(低位)存放在低地址 对于4字节的int a = 1,1自然是最低位,应该存放在最低地址,也就是首地址。
而大端(如网络传输中的字节序),就是高字节(高位)存放在低地址。
小端不符合人类的平时读写习惯,大端则符合人类的平时读写习惯。
5.
对于c语言程序在Linux下的执行过程(简单过程)
预处理 编译 汇编 链接
.c ——> .i ——> .s ——> .o ——> a.out
1.预处理过程
主要处理
1.宏定义
2.条件编译指令
3.头文件包含指令
2.编译阶段
1.通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。
2.优化
经过优化得到的汇编代码必须经过汇编程序的汇编转换成相应的机器指令,方可能被机器执行。
3.汇编阶段
把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。
目标文件由段组成。
代码段 该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段 主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。
4.链接程序
将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。
链接处理可分为两种:
(1)静态链接
(2)动态链接
整个面试下来的感受
说实话,一共面试了4轮,正常的三轮面试再加上加面(PS:一轮结果待定,所以才有的加面,实际在公司面试中都没有加面的)。总觉得面试时有点发虚,可能是题目有点难,有的地方不怎么太弄懂导致的,也可能最后被3G三面刷的阴影还在。尤其一面的时候,把自己总觉得压得太紧了,说都不敢说,晚上就有学长学姐给我聊,说如果放开一些,效果会更好。当然后来的面试越来越放得开吧。实际面试的过程也算是一个学习的过程,当被问到模糊和不清楚的只是后就开始去查、去问,当有不明白的东西,试着去临时想办法解决。实际面试下来,发现Linux的面试并不是想象中的那么可怕,更多的人都是由那份面试题引起内心的恐惧,不想去钻研,感觉面试的流程太多,担心不能通过面试,于是很多的人都在中途放弃了。最后一面的时候,学长也告诉了我很多话,小组会考虑报名者的院系,如果不是计算机院的担心他们坚持不下来,再加上你是个男孩子,所以面试时的要求更高一些,要求基本工要更加的扎实,而且要去坚持,技术这个东西永远都是拿时间和效率来衡量的,而且贵在坚持。最后也很感谢自己吧,在期中考试和实验班课程的繁忙中,依然坚持着面试和不断学习,其中的痛苦除了自己谁也不知道(看面试题到一两点,早上六点初继续起床读英语),最然水平还很菜,最后还是通过了面试(也应该是实验班的第一个进小组,默默吹一下,就当往届的学长学姐们都看不上吧)。希望在小组的接近两年里,努力学习,虚心请教,快乐生活,不辜负青春。