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
涉及到取值范围的问题,char类型的取值范围为-128~127
255是一个整数,在计算机中存储数据采用补码的形式,而正数原码补码相同,即
原码 1111 1111
反码 1111 1111
补码 1111 1111
有符号数正数最高位是0,所能取到的最大值为127,而128超过了这个范围。
2.
下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
char *str = "Xi You Linux Group 20";
printf("%d\n", printf(str));
return 0;
}
---------------------------------------------------
Xi You Linux Group 2021
解析:
本题考察printf()函数的返回值,查看man手册我们可以知道:Upon successful return, printf() return the number of characters printed.(成功返回后,printf() 返回打印的字符数。)
即printf()函数返回打印的字符数。"Xi You Linux Group 20"有21个字符(包括空格),则先打印str,后打印返回值21
6
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
解析:
本题重点在于两个变量:m、n
其中:m是具有静态存储期的块作用域变量,n是具有自动存储期的块作用域变量
所谓具有静态存储期,其实就是指该变量储存在静态内存中,它从程序被载入到程序结束期间都存在。
4.
下面程序会出现什么结果?为什么会出现这样的结果?
int main(int argc, char * argv[])
{
char ch = 'A';
int i = 65;
unsigned int f = 33554433;
*(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
解析:
本题考察移位运算符 >>/<<与ascii码的理解,重难点在变量f
*(int *)&f,考察取地址、强制类型转换以及解引用的知识。
在进行位移运算之前,先将f转化为二进制,然后再按位右移:
10000000000000000000000001 ==> 00000000000000000000000010 (2)
'?'的ascii码为63,63(?) + 2 = 65(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 = 0x7fff604b9900 &a[0] = 0x7fff604b9900 &a[0][0] = 0x7fff604b9900
&a+1 = 0x7fff604b9910 &a[0]+1 = 0x7fff604b9908 &a[0][0]+1 = 0x7fff604b9904
数组名
注意,输出的结果为16进制,因此9900在加16字节之后变为9910。
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[0] = 0, array[1] = 1, array[100] = 100
---------------------------------------------------
问题
函数get_array()返回的array是一个局部变量的地址
在函数get_array()结束之后,该地址内存上的数据被清除
即返回的是一个垃圾地址
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
本题考察对转义字符的理解
其中%zu输出size_t即unsigned int;
字符数组x中:\t表示移到下一个水平制表位,\b将当前位置移到前一列,\106表示’F’,106在ascii码中表示八进制的’F’。
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);
}
---------------------------------------------
第二个sacnf()输入的值
scanf()
scanf()是将读取到的数据存入一个内存地址中
第一个scanf()将变量a的地址赋值给变量c,这时变量c的内存存储的值为变量a的内存地址;
我们注意到:第二个scanf()没有取地址符’&’,因此,scanf()将输入的值赋值给地址&a
10.
请问一个 C 语言程序从源代码到可执行文件中间会进行哪些过程,你能简单描述一下
每个环节都做了什么事情吗?
点此
因前几次面试题已有类似的题目,在此省略
11.
请解释一下这行代码做了什么?
puts((char*)(int const[]){
0X6F796958,0X6E694C75,0X72477875,
0X3270756F,0X313230,0X00000A
});
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;
}
--------------------------------------------------
输入:edcba
输出:abcde
13.
用循环和递归求 Fibonacci 数列,你觉得这两种方式那种更好?说说你的看法。如果让你求 Fibonacci 数列的第 100 项,你觉得还可以用常规的方法求解吗?请试着求
出前 100 项的值(tip 大数运算)。