linux兴趣小组2017面试题
1. 分析下列程序的输出.
int main(int argc, char *argv[])
{
int t = 4;
printf("%lu\n", sizeof(t--));
printf("%lu\n", sizeof("ab c\nt\012\xa1*2"));
return 0;
}
- 若运行printf(“%d\n”,t); 结果为4,因为sizeof是关键字,且其后面的内容在编译时运算并替换为运算后的数值,在运行程序时直接调用替换值,不再进行t–的运算,故t仍是4.
- 在进行sizeof运算时,\n、 \012、 \xa1 分别为一个字符,且包含结束符\0.
2. 下面代码会输出什么?
int main(int argc, char *argv[])
{
int a = 10, b = 20, c = 30;
printf("%d %d\n", b = b*c, c = c*2) ;
printf("%d\n", printf("%d ", a+b+c));
return 0;
}
- printf函数的运行机制为在栈上申请存储空间, 规则为先进后出, 因此printf()表现为参数从右向左运算, 即 c = 60 (c = 2), b = 1200 (b = c).
- printf函数的返回值为所打印字符的列宽(长度).
3.下面代码使用正确吗?若正确,请说明代码的作用;若不正确,请指出错误并修改。
void get_str(char *ptr)
{
ptr = (char*)malloc(17);
strcpy(ptr, "Xiyou Linux Group");
}
int main(int argc, char *argv[])
{
char *str = NULL;
get_str(str);
printf("%s\n", str);
}
- 主函数中的指针变量str指向空指针, 在作为参数传进函数 get_str 时传给 ptr 时, 在被调函数中仅仅将 ptr 指向的内存地址变为了malloc函数申请的空间, 而主函数中的str仍指向空指针,并不会输出字符.
解决方法:
1) 使用二级指针void get_str(char **ptr) { *ptr = (char*)malloc(17); strcpy(*ptr, "Xiyou Linux Group"); } int main(int argc, char *argv[]) { char *str = NULL; get_str(&str); printf("%s\n", str); }
2) 使用函数返回值将新地址返回
char * get_str(char *ptr) { ptr = (char*)malloc(17); strcpy(ptr, "Xiyou Linux Group"); return ptr; } int main(int argc, char *argv[]) { char *str = NULL; str = get_str(str); printf("%s\n", str); }
4. 请解释下面代码的输出结果。
size_t q(size_t b)
{
return b;
}
size_t (*p(char *str))(size_t a)
{
printf("%s\n", str);
return q;
}
int main(int argc, char *argv[])
{
char str[] = "XiyouLinuxGroup";
printf("%lu\n", p(str)(strlen(str)));
return 0;
}
- 该题考察的点为返回值为函数指针的函数(详情见《LinuxC 编程实战》P78).
- size_t (*p(char *str))(size_t a)是一个返回值为函数指针的函数,首先看 p ,因为()的优先级比*高,所以p先与()结合,p(char *str)是含有字符型指针参数的函数,返回值是size_t (*)(size_t a),也就是一个指向函数的指针.该指针指向的函数有size_t类型的参数.
9. 说明下面程序的运行结果。
int main(int argc, char *argv[])
{
int a, b = 2, c = 5;
for(a = 1; a < 4; a++)
{
switch(a)
{
b = 99;
case 2:
printf("c is %d\n", c);
break;
default:
printf("a is %d\n", a);
case 1:
printf("b is %d\n", b);
break;
}
}
return 0;
}
输出结果为:
b is 2 c is 5 a is 3 b is 2
switch 中 case 之上的语句(赋值语句,输出语句等)会被跳过, 在本题中表现为 b = 99; 被跳过, 因此b的值仍为2.
14. 请修改下面的 swap 函数,使得既可以交换 int 类型的参数,也可以交换 double 类型的参数。
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
- 可以用宏定义:
#define swap(a, b) ((x)=(x)+(y),(y)=(x)-(y),(x)=(x)-(y))
- 多加一个参数代表数字所占字节数,并使用memcpy函数:
void swap(int *a, int *b, int size)
{
char buffer[8];
memcpy(buffer, a, size);
memcpy(a, b, size);
memcpy(b, buffer, size);
}
16. 请设计一个程序,通过命令行参数接收一个文件名 filename.txt( 纯文本文件 ) 和一个整型数字 n,实现从 filename.txt 中删除第 n 行数据。
17.解释程序输出结果
struct node
{
char a;
short b;
int c;
};
int main(int argc, char *argv[])
{
struct node s;
memset(&s, 0, sizeof(s));
s.a = 3;
s.b = 5;
s.c = 7;
struct node *pt = &s;
printf("%d\n", *(int*)pt);
printf("%lld\n", *(long long *)pt);
return 0;
}
- 本题主要考察
大小端
、内存对齐
、强制类型转换
问题。 大小端 : 一般电脑采用小端,即存储时“低位在前,高位在后”,例如整型1在存储时二进制码为
0000...0001
(31个0, 1个1),而在内存中存储时,实际存放顺序为
00000001
00000000
00000000
00000000
为了提高计算机读取内存内容的速度,采用的内存对齐的方法,各变量存储的首地址必须为 自身所占内存大小 的整数倍。因为该结构体中a占1字节, b占2字节, c占4字节, 若a,b之间无空字节,则c首地址将会是3(设首地址为0), 且b首地址将是1, 不符合规则, 因此在a后添加一个空字节(内容全为0),以及技能性内存对齐;
- 强制类型转换 : 以
(int*)pt
为例,将该数组强制转化为 int 型,即读取时只读取前四个字节的内容,再转化为整型输出。 - 深入了解请看大佬的博客