西邮Linux兴趣小组2022纳新面试题题解
感谢 Zhilu 重新录入题目原件
- 本题目只作为
Xiyou Linux兴趣小组2022纳新面试的有限参考。- 为节省版面,本试题的程序源码省去了
#include指令。- 本试题中的程序源码仅用于考察C语言基础,不应当作为C语言「代码风格」的范例。
- 题目难度随机排列。
所有题目编译并运行于x86_64 GNU/Linux环境。学长寄语:
长期以来,西邮Linux兴趣小组的面试题以难度之高名扬西邮校内。我们作为出题人也清楚的知道这份试题略有难度。请别担心。若有同学能完成一半的题目,就已经十分优秀。 其次,相比于题目的答案,我们对你的思路和过程更感兴趣,或许你的答案略有瑕疵,但你正确的思路和对知识的理解足以为你赢得绝大多数的分数。最后,做题的过程也是学习和成长的过程,相信本试题对你更加熟悉的掌握C语言的一定有所帮助。祝你好运。我们FZ103见!
0. 我的计算器坏了?!
2^10=1024对应于十进制的4位,那么2^10000对应于十进制的多少位呢?
计算一个数十进制的位数,我们以10为底求该数的对数,再取整+1,同理计算一个数对应的二进制的位数,以2为底求该数的对数再+1,[10000*log2]+1大概是3011位
1. printf还能这么玩?
尝试着解释程序的输出。
int main(void) {
if ((3 + 2 < 2) > (3 + 2 > 2)) printf("Welcome to Xiyou Linux Group\n"); else printf("%d\n", printf("Xiyou Linux Group - 2%d", printf(""))); }
讯享网
printf返回打印字符的个数
所以输出结果是Xiyou Linux Group - 2022
2. 你好你好你好呀!
- 程序的输出有点奇怪,请尝试解释一下程序的输出吧。
- 请谈谈对
sizeof()及strlen()的理解吧。
讯享网int main(void) {
char p0[] = "Hello,Linux"; char *p1 = "Hello,Linux"; char p2[11] = "Hello,Linux"; printf("p0==p1: %d, strcmp(p0,p2): %d\n", p0 == p1, strcmp(p0, p2)); printf("sizeof(p0): %zu, sizeof(p1): %zu, sizeof(*p2): %zu \n", sizeof(p0), sizeof(p1), sizeof(*p2)); printf("strlen(p0): %zu, strlen(p1): %zu\n", strlen(p0), strlen(p1)); }
sizeof()是基本的运算符 得到目标所占内存的大小
strlen()是包含在<string.h>库里的库函数 针对字符串 返回字符传的长度(字符个数)
- answer:>
sizeof(*p2)是第一个字符的首地址,大小为1,strlen计算的是长度所以大小都为11
3. 换个变量名不行吗?
请结合本题,分别谈谈你对C语言中「全局变量」和「局部变量」的「生命周期」理解。
int a = 3; void test() {
int a = 1; a += 1; {
int a = a + 1; printf("a = %d\n", a); } printf("a = %d\n", a); } int main(void) {
test(); printf("a= %d\n", a); }
三次打印
- 打印
随机值因为在其作用域中 a变量仅声明 未进行定义 - 打印
a = 2此处的a是test函数中定义的a - 打印
a= 3此处的a是全局变量a
4. 内存对不齐
union与struct各有什么特点呢,你了解他们的内存分配模式吗。
讯享网typedef union {
long l; int i[5]; char c; } UNION; typedef struct {
int like; UNION coin; double collect; } STRUCT; int main(void) {
printf("sizeof (UNION) = %zu \n", sizeof(UNION)); printf("sizeof (STRUCT) = %zu \n", sizeof(STRUCT)); }
结构体内存对齐: >https://www.zhihu.com/question/ 联合体相关知识点: >https://blog.csdn.net/m0_/article/details/?ops_request_misc=&request_id=&biz_id=102&utm_term=%E8%81%94%E5%90%88%E4%BD%93%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86%E7%82%B9&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-.142^v65^control,201^v3^control_1,213^v2^t3_esquery_v1&spm=1018.2226.3001.4187
- 答案: >
-
讯享网
输出 sizeof(UNION) = 24 sizeof(STRUCT) = 40
5. Bitwise
- 请使用纸笔推导出程序的输出结果。
- 请谈谈你对位运算的理解。
int main(void) {
unsigned char a = 4 | 7; a <<= 3; unsigned char b = 5 & 7; b >>= 3; unsigned char c = 6 ^ 7; c = ~c; unsigned short d = (a ^ c) << 3; signed char e = -63; e <<= 2; printf("a: %d, b: %d, c: %d, d: %d \n", a, b, c, (char)d); printf("e: %#x \n", e); }
- |是或,两个位都为0,结果才为0,4是0100,7是0111,4|7结果是0111=7,左移三次7*2=14,14 *2=28,28 *2=56
- 所以a=56
- &是与,两个位都为1时结果才为1,5是0101,7是0111,5&7结果是0101=5,5右移三次5/2=2,2/2=1,1/2=0
- 所以b=0
- ^是异或,两个位相同为0,相异为1,6是0110,7是0111,结果是0001,~是取反,结果是1111 1110,
- 所以c=254
- a是0011 1000,c是1111 1110,a^c的结果是0000 0000 1100 0110左移3位是0000 0110 0011 0000转换为char是0011 0000=48,e是1011 1111补码是1100 0001左移2位是0000 0100=4,
- 所以e=4
位运算:>https://www.runoob.com/w3cnote/bit-operation.html
整形提升和算数转换:> https://blog.csdn.net/iqrmshrt/article/details/
数据储存(源码反码补码):> https://zhuanlan.zhihu.com/p/
- 答案: >
讯享网
输出 a: 56,b: 0,c: 255,d: 56 e: 0x4
6. 英译汉
请说说下面数据类型的含义,谈谈
const的作用。
char *const p。char const *p。const char *p。
- 关于const
int x = 1,y = 2; // a 与 b 都是整型常量,值都不能修改,只读变量 const int a = 0; int const b = 0; const int *px = &a;// px 不是常量 *px 是常量 int * const py = &y;// py 是常量 *py 不是常量 const int * const pp = &x;// pp 与 *pp 都是常量 /* 1、如果 const 在 * 前面,修饰的是数据类型,指向的内容不 能修改 2、如果 const 在 * 后面,修饰的是变量,变量是常量 3、如果 const 在 * 前后都有,都是常量 */
7. 汉译英
请用变量
p给出下面的定义:
- 含有10个指向
int的指针的数组。- 指向含有10个
int数组的指针。- 含有3个「指向函数的指针」的数组,被指向的函数有1个
int参数并返回int。
函数指针的声明及相关知识点;https://blog.csdn.net/Topdandan/article/details/
- 答案: >
讯享网
int *p [10]; int (*p)[10]; int (*p[3])(int);
8. 混乱中建立秩序
提示:动动你的小手敲出来更好哦~
就… 算法 (网上自己搜 例如 [ 冒泡 / 选择 / 归并…排序 ])
9. 手脑并用
提示:你需要为新字符串分配空间。
char* convertAndMerge(/*补全签名*/); int main(void) {
char words[2][20] = {
"Welcome to Xiyou ", "Linux Group 2022"}; printf("%s\n", words[0]); printf("%s\n", words[1]); char *str = convertAndMerge(words); printf("str = %s\n", str); free(str); }
讯享网- 动态规划内存:>https://blog.csdn.net/m0_/article/details/?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E5%86%85%E5%AD%98&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-.142^v65^control,201^v3^control_1,213^v2^t3_esquery_v1&spm=1018.2226.3001.4187
- answer:>
char* convertAndMerge(char word[][20]); int main(void) { char words[2][20] = { "Welcome to Xiyou ", "Linux Group 2022"}; printf("%s\n", words[0]); printf("%s\n", words[1]); char* str = convertAndMerge(words); printf("str = %s\n", str); free(str); } char* convertAndMerge(char word[][20]) { char *a = (char *)malloc(sizeof(char)*20*2); sprintf(a,"%s%s",word[0],word[1]); return a ; }
10. 给你我的指针,访问我的心声
程序的输出有点奇怪,请尝试解释一下程序的输出吧。
讯享网int main(int argc, char **argv) {
int arr[5][5]; int a = 0; for (int i = 0; i < 5; i++) {
int *temp = *(arr + i); for (; temp < arr[5]; temp++) *temp = a++; } for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%d\t", arr[i][j]); } } }
这里是输出:>
0 1 2 3 4 25 26 27 28 29 45 46 47 48 49 60 61 62 63 64 70 71 72 73 74
- 未开始时
arr[][]内部是
讯享网[0] 0 0 0 0//temp位置 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 所以 当外层循环 i=0 跑完时
// i = 0 时 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [*]//当我的指针走到[*]时 出循环
i++;
然后 temp = *(arr+i)
进入循环 继续++ 赋值
讯享网0 1 2 3 4 [5] 6 7 8 9 //[temp]位置 即开始++赋值的位置 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
0 1 2 3 4 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 [*]//结束
然后同理
讯享网0 1 2 3 4 25 26 27 28 29 [30] 31 32 33 34 //启始位置下移 35 36 37 38 39 40 41 42 43 44
循环++赋值 直到temp位置 和 arr[5]重合
拿到答案:>
0 1 2 3 4 25 26 27 28 29 45 46 47 48 49 60 61 62 63 64 70 71 72 73 74
11. 奇怪的参数
你了解argc和argv吗?
直接运行程序argc的值为什么是1?
程序会出现死循环吗?
讯享网#include <stdio.h> int main(int argc, char **argv) {
printf("argc = %d\n", argc); while (1) {
argc++; if (argc < 0) {
printf("%s\n", (char *)argv[0]); break; } } }
- argc即arguments count表示传入main函数的参数个数
- argv即arguments value/vector参数值,表示传入main函数的参数序列或指针,并且第一个参数argv[0]一定是程序的名称
- argc为1,即该程序的路径名argc为int类型,不断+1,会数值溢出从而argc<0,break跳出循环
这里 argc和argv的用处不大 这二者在系统编程中运用较多\
12. 奇怪的字符
程序的输出有点奇怪,请尝试解释一下程序的输出吧。
int main(int argc, char **argv) {
int data1[2][3] = {
{
0x636c6557, 0x20656d6f, 0x58206f74}, // u o y i n i L \0 {
0x756f7969, 0x6e694c20, 0x00000000}}; int data2[] = {
0x, 0x70756f72, 0x, 0x00000a32}; char *a = (char *)data1; char *b = (char *)data2; char buf[1024]; strcpy(buf, a); strcat(buf, b); printf("%s \n", buf); if(*buf='W') printf("LE"); else printf("BE"); }
此程序将十六进制的内存编码进行分割 将int长度的编码分割成char长度进行输出
要注意的是 计算机是小端存储 在切割时 先打印的是0x57 也就是 W
- 输出:>
Welcome to Xiyou Linux Group 2022
13. 小试宏刀
- 请谈谈你对
#define的理解。- 请尝试着解释程序的输出。
讯享网#include <stdio.h> #define SWAP(a, b, t) t = a; a = b; b = t #define SQUARE(a) a *a #define SWAPWHEN(a, b, t, cond) if (cond) SWAP(a, b, t) int main() {
int tmp; int x = 1; int y = 2; int z = 3; int w = 3; SWAP(x, y, tmp); printf("x = %d, y = %d, tmp = %d\n", x, y, tmp); if (x > y) SWAP(x, y, tmp); printf("x = %d, y = %d, tmp = %d\n", x, y, tmp); SWAPWHEN(x, y, tmp, SQUARE(1 + 2 + z++ + ++w) == 100); printf("x = %d, y = %d,tmp=%d\n", x, y, tmp); printf("z = %d, w = %d ,tmp = %d\n", z, w, tmp); }
考察的是宏的相关问题
简而言之 宏定义会在预编译阶段被编译器插入到源代码中;
下面是预编译后的内容
int main() {
int tmp; int x = 1; int y = 2; int z = 3; int w = 3; tmp = x; x = y; y = tmp; printf("x = %d y = %d tmp = %d\n", x, y, tmp); if (x > y) tmp = x; x = y; y = tmp; printf("x = %d y = %d tmp = %d\n", x, y, tmp); if (1 + 2 + z++ + ++w *1 + 2 + z++ + ++w == 100) tmp = x; x = y; y = tmp; printf("x = %d, y = %d\n", x, y); printf("x = %d y = %d tmp = %d\n", z, w, tmp); }
- 输出:>
讯享网
x = 2 y = 1 tmp = 1 x = 1 y = 2 tmp = 2 x = 2, y = 2 x = 5 y = 5 tmp = 2
14. GNU/Linux命令 (选做)
你知道以下命令的含义和用法吗:
注:
嘿!你或许对Linux命令不是很熟悉,甚至你没听说过Linux。
但别担心,这是选做题,不会对你的面试产生很大的影响!
了解Linux是加分项,但不了解也不扣分哦!
lsrmwhoami请问你还了解哪些GNU/Linux的命令呢。
关于Linux常用的指令:> https://cloud.tencent.com/developer/article/
恭喜你做到这里!你的坚持战胜了绝大多数看到这份试题的同学。
或许你自己对答题的表现不满意,但别担心,请自信一点呐。
坚持到达这里已经证明了你的优秀。
还在等什么,快带上你的笔记本电脑,来FZ103面试吧!
西邮Linux兴趣小组2021纳新面试题题解
感谢 Zhilu 重新录入题目原件。好人一生平安。
注:
- 本题目仅作
西邮Linux兴趣小组2021纳新面试题的有限参考。- 为节省版面本试题的程序源码中省略了
#include指令。- 本试题中的程序源码仅用于考察C语言基础,不应当作为C语言代码风格的范例。
- 题目难度与序号无关。
- 所有题目均假设编译并运行
x86_64 GNU/Linux环境。
1. 大小和长度竟然不是一个意思
sizeof()和strlen()有什么异同之处?他们对于不同参数的结果有什么不同?请试举例子说明。
int main(void) {
char s[] = "I love Linux\0\0\0"; int a = sizeof(s); int b = strlen(s); printf("%d %d\n", a, b); }
同 22-1
2. 箱子的大小和装入物品的顺序有关
test1和test2都含有:1个short、1个int、1个double,那么sizeof(t1)和sizeof(t2)是否相等呢?这是为什么呢?
讯享网struct test1 {
int a; short b; double c; }; struct test2 {
short b; int a; double c; }; int main(void) {
struct test1 t1; struct test2 t2; printf("sizeof (t1) : %d\n", sizeof(t1)); printf("sizeof(t2): %d\n", sizeof(t2)); }
同 22-4
3. 哦,又是函数
想必在高数老师的教导下大家十分熟悉函数这个概念。那么你了解计算机程序设计中的函数吗?请编写一个
func函数,用来输出二维数组arr中每个元素的值。
/*在这里补全func函数的定义*/ int main(void) {
int arr[10][13]; for (int i = 0; i < 10; i++) {
for (int j = 0; j < 13; j++) {
arr[i][j] = rand(); } } func(arr); }
- answer:>
讯享网
void func(int n,char arr[][13]) { int i; for(i=0;i<n;i++) { printf("%s\n",i,arr[i]); } }//下面两个的函数体内部结构和这个一样,后面的不展开写了
4.就不能换个变量名吗?
- 请结合下面的程序,简要谈谈
传值和传址的区别。- 简要谈谈你对C语言中变量的生命周期的认识。
int ver = 123; void func1(int ver) {
ver++; printf("ver = %d\n", ver); } void func2(int *pr) {
*pr = 1234; printf("*pr = %d\n", *pr); pr = 5678; printf("ver = %d\n", ver); } int main() {
int a = 0; int ver = 1025; for (int a = 3; a < 4; a++) {
static int a = 5; printf("a = %d\n", a); a = ver; func1(ver); int ver = 7; printf("ver = %d\n", ver); func2(&ver); } printf("a = %d\tver = %d\n", a, ver); }
- 传值/传址
- 传值:传值相当于单纯把值传给别人,相当于复制粘贴的操作,传值不会改变传值方的值。
- 传址:传地址相当于将地址赋给了对方,也就是说两个参数此时就是绑在一起的蚂蚱,它们指向同一片地址。传址后两个参数只要有一个发生改变,另一个参数就会随之改变。
- 变量的生命周期
- 变量类型主要有全局变量、局部变量和静态变量。
- 局部变量:定义在函数体内部的变量,作用域仅限于函数体内部。离开函数体就会无效,再调用就是出错。
- 全局变量:所有的函数外部定义的变量,它的作用域是整个程序,也就是所有的源文件,包括.c和.h文件。
- 静态变量(static):变量在运行区间结束后内存不释放,地址不变。
- 名称重复时 将取
最小的作用域//这么理解应该可以
- 变量类型主要有全局变量、局部变量和静态变量。
5. 套娃真好玩!
请说明下面的程序是如何完成求和的?
讯享网unsigned sum(unsigned n) {
return n ? sum(n - 1) + n : 0; } int main(void) {
printf("%u\n", sum(100)); }
- 简单递归
- 函数作用是求和
- 输出
5050
- 输出
- 关于递归
- 归根结底还是进行函数调用
当c解决了 b就解决了 从而a就解决了
- 换成递归
当a3解决了 a2就解决了 从而a就解决了
6. 算不对的算术
void func(void) {
short a = -2; unsigned int b = 1; b += a; int c = -1; unsigned short d = c * 256; c <<= 4; int e = 2; e = ~e | 6; d = (d & 0xff) + 0x2022; printf("a=0x%hx\tb=0x%x\td=0x%hx\te=0x%x\n", a, b, d, e); printf("c=Ox%hhx\t\n", (signed char)c); }
数据的补码方式存储和位运算
动笔写
不懂原理的跳22-5的链接
- 输出:>
讯享网
a=0xfffe b=0xffffffff d=0x2022 e=0xffffffff c=0xf0
7. 指针和数组的恩怨情仇
int main(void) {
int a[3][3] = {
{
1, 2, 3}, {
4, 5, 6}, {
7, 8, 9}}; int(*b)[3] = a; ++b; b[1][1] = 10; int *ptr = (int *)(&a + 1); printf("%d %d %d \n", a[2][1], **(a + 1), *(ptr - 1)); }
答案 10 4 9
8. 移形换位之术
下面有
a、b、c三个变量和4个相似的函数。
- 你能说出使用这三个变量的值或地址作为参数分别调用这5个函数,在语法上是否正确吗?
- 请找出下面的代码中的错误。
const int和int const是否有区别?如果有区别,请谈谈他们的区别。const int *和int const *是否有区别?如果有区别,请谈谈他们的区别。
讯享网int a = 1; int const b = 2; const int c = 3; void funco(int n) {
n += 1; n = a; } void func1(int *n) {
*n += 1; n = &a; } void func2(const int *n) {
*n += 1; n = &a; } void func3(int *const n) {
*n += 1; n = &a; } void func4(const int *const n) {
*n += 1; n = &a; }
有关const的问题 前面有解释 和const和*的位置有关 判断是顶端const还是底端const
9. 听说翻转字母大小写不影响英文的阅读?
请编写
convert函数用来将作为参数的字符串中的大写字母转换为小写字母,将小写字母转换为大写字母。返回转换完成得到的新字符串。
char *convert(const char *s); int main(void) {
char *str = "XiyouLinux Group 2022"; char *temp = convert(str); puts(temp); }
answer:>
讯享网char *convert(const char *s) {
char *k=(char*)malloc(N); char *t=s; char *q=k; memset(k,0,N); char str[N]; for(;*s!='\0';*s++,k++) {
if(*s>='a'&&*s<='z') *k=toupper(*s); else if(*s>='A'&&*s<='Z') *k=tolower(*s); else *k=*s; } t=q; return t; }
10. 交换礼物的方式
- 请判断下面的三种
Swap的正误,分别分析他们的优缺点。- 你知道这里的
do {...} while(0)的作用吗?- 你还有其他的方式实现
Swap功能吗?
#define Swap1(a, b, t) \ do {
\ t = a; \ a = b; \ b = t; \ } while (0) #define Swap2(a, b) \ do {
\ int t = a; \ a = b; \ b = t; \ } while (0) void Swap3(int a, int b) {
int t = a; a = b; b = t; }
前两种方法正确,最后一种错误。
传值和传址问题
11. 据说有个东西叫参数
你知道
argc和argv的含义吗?请解释下面的程序。你能在不使用argc的前提下,完成对argv的遍历吗?
讯享网int main(int argc, char *argv[]) {
printf("argc = %d\n", argc); for (int i = 0; i < argc; i++) printf("%s\n", argv[i]); }
22-11
补充> argv是以NULL结尾的
可以用while(argv++!=NULL) printf("%s",*argv);来循环输出
12. 人去楼空
这段代码有是否存在错误?谈一谈静态变量与其他变量的异同。
int *func1(void) {
static int n = 0; n = 1; return &n; } int *func2(void) {
int *p = (int *)malloc(sizeof(int)); *p = 3; return p; } int *func3(void) {
int n = 4; return &n; } int main(void) {
*func1() = 4; *func2() = 5; *func3() = 6; }
静态变量具有全局作用域 在声明后重复定义 但声明仅仅只有一次 后续碰到声明会越过
13. 奇怪的输出
讯享网int main(void) {
int data[] = {
0x636c6557, 0x20656d6f, 0x78206f74, 0x756f7969, 0x6e694c20, 0x, 0x70756f72, 0x, 0x00000a31}; puts((const char*)data); }
和22年的题目一样
14. 请谈谈对从「C语言文件到可执行文件」的过程的理解
预处理 编译 汇编 链接
15. (选做) 堆和栈
你了解程序中的栈和堆吗?它们在使用上有什么区别呢?请简要说明。
int* fun() {
//..... int a;//栈区 int *b =(int *)malloc(sizeof(/*num*/));//堆区 return b; } int main() {
int *a=fun(); free(a); }
16. (选做) 多文件
一个程序在不使用任何头文件的情况下,如何使用另一个文件中的函数。
extern关键字
17. (选做) GNU/Linux与文件
- 你知道如何在
GNU/Linux下如何使用命令行创建文件与文
件夹吗?- 你知道
GNU/Linux下的命令ls 的每一列的含义吗?- 你知道
GNU/Linux下文件的访问时间、修改时间、创建时间如何查看吗?并简单说说他们的区别。
恭喜你做完了整套面试题,快来参加西邮Linux兴趣小组的面试吧!
西邮 Linux兴趣小组面试时间:
2021年10月25日至2021年10月31日晚8点。
听说面试来的早一点更能获得学长学姐的好感哦。我们在FZ103等你!
西邮Linux兴趣小组2020纳新试题题解
感谢 Zhilu 重新录入题目原件。好人一生平安。
注:
- 本题仅作为面试有限参考
- 为节省版面,省去所有
#include指令- 题目难度与序号无关
- 若无特殊声明,均假设在
Linux x86_64 GCC编译器环境下
1. 请试着解释其输出。
讯享网int main(int argc , char *argv[]) {
unsigned char a = 255; char ch = 128; a -= ch; printf("a = %d ch = %d\n", a, ch); }
- 输出:>
a = 127 ch = -128
- 当右值的数据长度大于左值的数据长度时 赋值过程将发生截断
- 当同等长度的无符号数和有符号数进行运算时 会将有符号数转化为无符号数
2. 下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[]) {
char *str = "Xi You Linux Group 20"; printf("%d\n", printf(str)); return 0; }
printf()的返回值 看22年的题
3. 这段代码的输出结果是什么?为什么会出现这样的结果?
讯享网int i = 2; void func() {
if(i != 0) {
static int m = 0; int n = 0; n++; m++; printf("m = %d, n = %d\n", m, n); i--; func(); } else {
return; } } int main(int argc, char *argv[]) {
func(); return 0; }
- 输出
m = 1, n = 1 m = 2, n = 1 - 递归和静态变量
4. 下面程序会出现什么结果?为什么会出现这样的结果?
讯享网int main(int argc, char * argv[]) {
char ch = 'A'; int i = 65; unsigned int f = ; *(int *)&f >>= 24; *(int *)&f = *(int *)&f + '?'; printf("ch = %c i = %c f = %c\n", ch, i, *(int *)&f); return 0; }
- 输出
ch = A i = A f = A
位运算 类型转换
5. 下面代码的运行输出结果是什么,并说说你的理解。
讯享网int main(int argc, char *argv[]) {
int a[2][2]; printf("&a = %p\t&a[0] = %p\t&a[0][0] = %p\n", &a, &a[0], &a[0][0]); printf("&a+1 = %p\t&a[0]+1 = %p\t&a[0][0]+1= %p\n", &a+1, &a[0]+1, &a[0][0]+1); return 0; }
- 输出
&a = 0x7ffcfe86ddf0 &a[0] = 0x7ffcfe86ddf0 &a[0][0] = 0x7ffcfe86ddf0 &a+1 = 0x7ffcfe86de00 &a[0]+1 = 0x7ffcfe86ddf8 &a[0][0]+1= 0x7ffcfe86ddf4
数组的实质–>存放数据的地址
6. 下列程序的功能是什么?有什么问题,你能找出问题并解决它吗?
讯享网int* get_array() {
int array[1121]; for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
array[i] = i; } return array; } int main(int argc, char *argv[]) {
int *p = get_array(); }
问题:> 传回的array指向的内存在get_array()返回时就被销毁了(//21年里说的栈区)
7. 下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[]) {
char str[] = "XiyouLinuxGroup"; char *p = str; char x[] = "XiyouLinuxGroup\t\106F\bamily"; printf("%zu %zu %zu %zu\n", sizeof(str), sizeof(p), sizeof(x), strlen(x)); return 0; }
- 输出
讯享网
16 8 25 24
sizeof()实际运算的个体
16–str内存占用的大小
8 --指针的大小
25–x的大小
24–x串的长度
8. 如下程序,根据打印结果,你有什么思考?
int add(int *x, int y) {
return *x = (*x^y) + ((*x&y)<<1); } int a; int main(int argc, char *argv[]) {
int b = 2020; if(add(&b, 1) || add(&a, 1)) {
printf("XiyouLinuxGroup%d\n", b); printf("Waiting for y%du!\n", a); } if(add(&b, 1) && a++) {
printf("XiyouLinuxGroup%d\n", b); printf("Waiting for y%du!\n", a); } return 0; }
- 输出
讯享网
XiyouLinuxGroup2021 Waiting for y0u!
9. 在下段程序中,我们可以通过第一步打印出a的地址,假如在你的机器上面打印结果是0x7ffd737c6db4;我们在第二步用scanf函数将这个地址值输入变量c中;第三步,随机输入一个数字,请问最终输出了什么结果,你知道其中的原理吗?
void func() {
int a = 2020; unsigned long c; printf("%p\n", &a); printf("我们想要修改的地址:"); scanf("%lx", &c); printf("请随便输入一个数字:"); scanf("%d", (int *)c); printf("a = %d\n", a); }
10. 请问一个C语言程序从源代码到可执行文件中间会进行哪些过程,你能简单描述一下每个环节都做了什么事情吗?
预处理 编译 汇编 链接
11. 请解释一下这行代码做了什么?
讯享网puts((char*)(int const[]){
0X6F,0X6E694C75,0X, 0XF,0X,0X00000A });
打印XiyouLinuxGroup2021
和前两年一样
12. 请随机输入一串字符串,你能解释一下输出结果吗?
int main(int argc, char *argv[]) {
char str[1121]; int key; char t; fgets(str, 1121, stdin); for(int i = 0; i < strlen(str) - 1; i++) {
key = i; for(int j = i + 1; j < strlen(str); j++) {
if(str[key] > str[j]) {
key = j; } } t = str[key]; str[key] = str[i]; str[i] = t; } puts(str); return 0; }
14. Linux 实操题
请通过命令创建一个目录,在该目录中创建几个后缀为
.Linux的文件,然后通过命令查询这几个文件的基本属性信息(如文件大小,文件创建时间等),之后使用命令查看该目录下文件名含有“.Linux”的文件的数量(不包括子目录下的文件),把得到的数字写入到一个文件中,最后删除此目录。
前面的linux命令操作有
DONE

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/46109.html