1. 请试着解释其输出。
1 | int main(int argc , char *argv[]) { |
a的值为127,无符号字符型a为255-128=127,而ch为128超过char的最大范围,输出-128
2. 下面代码的运行输出结果是什么,并说说你的理解。
1 | int main(int argc, char *argv[]) { |
先打印字符串str:”Xi You Linux Group 20”,然后printf的返回值为21,外层的printf打印21,故最终结果是”Xi You Linux Group 2021”
- priintf函数的返回值为成功打印的数字或字符;
- scanf函数的返回值为成功输入的数据个数;
3. 这段代码的输出结果是什么?为什么会出现这样的结果?
1 | int i = 2; |
4. 下面程序会出现什么结果?为什么会出现这样的结果?
1 | int main(int argc, char * argv[]) { |
关于运算中的类型转换有两个通用的指导原则:
1.为了防止数据精度损失,如果有必要的话,类型总是被提升为较宽的类型
2.所有含有小于整数类型的算术表达式在计算之前其类型被提升为整形数据类型
5. 下面代码的运行输出结果是什么,并说说你的理解。
1 | int main(int argc, char *argv[]) { |
1 | /* test */ |
&a,&a[0],&a[0] [0]地址都相同
&a代表整个数组的地址,&a[0]表示数组第一行的地址,&a[0] [0]表示首元素的地址
&a+1表示整个数组的地址加上一个数组类型大小的地址(2*2 *int),相当于&b
&a[0]+1表示第一行的地址加上一行类型大小的地址(2*int),相当于&a[1]
&a[0] [0]+1表示首元素地址加上一个元素类型大小的地址(int),相当于&a[0] [1]
6. 下列程序的功能是什么?有什么问题,你能找出问题并解决它吗?
1 | int* get_array() { |
get_array函数原意是想返回指向数组array的指针,从而输出array数组中的值,但是array在函数结束后会自动释放内存而找不到array数组的地址,从而使p成为野指针
修改如下:
1 |
|
7. 下面代码的运行输出结果是什么,并说说你的理解。
1 | int main(int argc, char *argv[]) { |
8. 如下程序,根据打印结果,你有什么思考?
1 | int add(int *x, int y) { |
9. 在下段程序中,我们可以通过第一步打印出a
的地址,假如在你的机器上面打印结果是0x7ffd737c6db4
;我们在第二步用scanf
函数将这个地址值输入变量c
中;第三步,随机输入一个数字,请问最终输出了什么结果,你知道其中的原理吗?
10. 请问一个C语言程序从源代码到可执行文件中间会进行哪些过程,你能简单描述一下每个环节都做了什么事情吗?
(1)预处理阶段。预处理器(cpp)根据字符#开头的命令,修改原始的C程序。
(2)编译阶段。将c语言文件从高级语言转为汇编语言。
(3)汇编阶段。将汇编语言转化为二进制语言。
(4)链接阶段。将使用的头文件与本文件链接起来。
11. 请解释一下这行代码做了什么?
1 | puts((char*)(int const[]){ |
12. 请随机输入一串字符串,你能解释一下输出结果吗?
1 | int main(int argc, char *argv[]) { |
fgets() 虽然比 gets() 安全,但安全是要付出代价的,代价就是它的使用比 gets() 要麻烦一点,有三个参数。它的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
其中:s 代表要保存到的内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream 表示从何种流中读取,可以是标准输入流 stdin,也可以是文件流,即从某个文件中读取。标准输入流就是输入缓冲区。所以如果是从键盘读取数据的话就是从输入缓冲区中读取数据,即从标准输入流 stdin 中读取数据,所以第三个参数为 stdin。
13. 用循环和递归求Fibonacci
数列,你觉得这两种方式那种更好?说说你的看法。如果让你求Fibonacci
数列的第100项,你觉得还可以用常规的方法求解吗?请试着求出前100项的值(tip大数运算)。
递归虽然有简洁的优点,但它同时也有显著地缺点。递归由于是函数调用自身,而函数调用是有空间和时间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。
而且除了效率问题之外,递归可能引起 调用栈溢出,因为需要为每一次函数调用在内存栈中分配空间,而每个进程的栈的容量是有限的。当蒂固的层级太多,就会超出栈的容量,导致栈溢出。比如上边的代码,输入40,可以正确返回 12502500,但是输入 5000 就会出错。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1qYdVoar-1668850172001)(/home/shawn/下载/picture/20181211162634168.png)]
如果计算数列的第4个位置上(从0开始)的数(0 1 1 2 3),也就是3,上边的 printf 输出应该是 4 3 2 1 0 1 2 1 0,这是因为计算 F(4) 要计算 F(3) 和 F(2),而计算 F(3) 的时候又要计算 F(2) 和 F(1),所以会有很多重复计算。
14. Linux 实操题
请通过命令创建一个目录,在该目录中创建几个后缀为
.Linux
的文件,然后通过命令查询这几个文件的基本属性信息(如文件大小,文件创建时间等),之后使用命令查看该目录下文件名含有“.Linux
”的文件的数量(不包括子目录下的文件),把得到的数字写入到一个文件中,最后删除此目录。