目录
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),手动加括号。