西邮Linux兴趣小组2019-2021年纳新面试题解析

目录

2019年

2020年

2021年


2019年


1、

结果:无限打印“ = ”

大家都知道在码长为16位的情况下,int 的取值范围为-32768~32767,而unsinged int即无符号整形的范围为0~65535

那么问题来了哈,unsigned int类型如果遇到的赋值为负数,它会怎么处理呢?

答案是它会以补码的形式转换表示。

回归到本题:当for循环最后一次将unsigned int类型的i自减为-1时,此时i将会变成其十进制补码:65535。而跳脱for循环的条件是i<0,但每每i想要成为负数的那一刻,啪,直接给转为正数补码了,所以无法结束这个循环,也就只能一直打印“ = ”了。


2、

 (1)主要引用了一个中间变量c,可看作它是一个空杯子,相当于一个交换媒介。先把a的值暂存于“空杯子"c中,再把b的值赋给a,最后将”空杯子“c(也就是a)的值赋给b,即完成了数值交换的操作。

(2)这就是一个数学上的简单交换障眼术。

(3)使用异或进行解决。对于两个值来说,异或结果为:同0异1

例如两个整数a=10100001,b=00000110,可通过下列语句实现交换:

  a = a^b;   //a=10100111

  b = b^a;   //b=10100001

  a = a^b;   //a=00000110

于是a、b就这样交换了数值。


3、

 结果:输出结果不一致,每调用一次函数,a值就递增1,而b值始终为1。

这道题主要涉及局部变量和static关键字的作用。我们在程序中多次调用的输出如下:

首先我们知道a、b都定义在函数体内,为局部变量。而局部变量一旦离开了定义它的代码块时,声明周期结束,变量就会被销毁,无法再继续使用(所以每调用一次函数结束时,b都会被清零,b固然每次都为1)

那凭什么a每次都能递增?那是因为此时对a设定了“static”—a就变成了局部静态变量

局部静态变量

作用域同样为局部作用域,同样也是当定义它的函数结束时,作用域结束。但是!当局部静态变量离开作用域后,其本身数据并没有被销毁,而是留在了内存当中。直到该函数再次被调用,此值就会在原值的基础上做改变

也就是说,每调用一次函数对a实现++时,最后的结果都被保存在了内存中没被清零,因此a呈递增状态。 ( static就相当于局部变量值的“保护伞”啦!)


4、

结果:Xiyou Linux Group2019

主要考察printf函数的返回值

printf函数返回其成功打印字符的个数包括空格、换行符'\n'本题的输出自右往左,第一个输出没有内容,因此'%d'处的值为0;接着第二个函数输出为'Xiyou Linux Group20';第三处使用第二处打印的返回值(打印字符个数)为19。最后连起来即为输出结果。


5、

 结果:-1 0

(a是啥!a没声明也没初始化又不能当作常量赋值,就导致编译错误了,小问题这应该是题目不小心打错了)修改后代码如下:

本题和第一题类似,都是考察数据类型的范围越界问题

  • unsigned char(无符号型)的范围为0~255
  • signed char即 char(有符号型)的范围为-128~127。

那么为什么这里的255输出为-1呢?是不是char类型的问题?那接下来我们试试“255”对于int类型和char类型的输出分别是多少

int main(int argc,char *argv[])
{
	char ch = 255;
	int sh = 255;
	printf("ch = %d\nsh = %d\n",ch,sh);
}

结果输出为:

我们看到int类正常输出255,而char类输出却为-1

首先在计算机中,存储数据采用补码的形式存储

所以当255作为int类型来声明时,因为没有超出int类型的有效范围,并且作为正数的255的二进制原反补码都相同,即都为1111 1111(255),因此以int类型来定义时其输出值为255;

再来看看,当255以char类型来声明时,因为有符号char型范围是-128~127:

完全可以将其范围看作是一个头接尾的圆圈,一个圈所容纳的数据数量恰好为256(127+128还有0的存在再+1),也就代表着我们可以把255当作是这个圈内的第255个元素,也就是-1了。

用式子表达就是:在255中,当到127+1越界后变为-128(即跳到负数表达范围内),-128再与((255-127)-1)相加=(-128+127)=-1。


6、

结果为:x=-1, y=4, t=-1 // x=0, y=5, t=1

本题对于x和y的输出很简单,就是普通的加操作。重点在于t的两个输出,这其中涉及的两个运算符是:‘ | ’和‘ || ’

运算符|

指的是对两数的二进制补码进行按位或运算,有1则1,注意最后的结果也为补码形式。(‘ & ’有0则0)

逻辑运算符||

如果两个数中有一个为非零,则为真(1)。(‘ && ’两个数都为非零才为真)

同时注意进行运算时,x先++再(运算/判断),y先(运算/判断)再++

也就是说当执行代码段第三行时,x值为-1、y值为3,此时进行按位或运算。-1的二进制补码表示为1111 1111,谁碰上它进行或运算每位都必为1,最终结果都必为-1(1111 1111 ),因此第一个t的输出为-1。

同理,当执行代码段第五行时,x的值为0、y值为4,此时进行逻辑或判断。判断开始时已判断x为正,因此逻辑判断为真返回1,所以第二个t的输出为1。


7、

瞧这个大坑,你是不是看到“输出为4”的坑就呼呼往里头栽?(反正我是)

看看人家输出:

 人家输出的是3。

不要以为这里面的 X*X =(1+1)*(1+1)= 4,这是人脑思维。计算机在#define宏定义的时候接受的是X = a*b,那它在后续计算的时候只会傻愣往里头代 a*b 而不是(a*b),所以此时X*X = 1+1*1+1=3。

你的初衷如果是想要它输出4,那你就要把宏定义改为:#define X (a+b),手动加括号。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜 然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值