IceSandwich

C语言题目的陷阱

记录踩坑

字数统计: 821阅读时长: 3 min
2019/01/13 Share

经过对C语言题目的复习,发现有很多有xian趣jing的题目,于是记录一下。

进制转换、char占据字节、反码补码

1
2
3
4
5
6
//以下程序的输出结果是 ____
#include <stdio.h>
void main() {
char c = 0345;
printf("%d\n", c);
}

从代码可以知道,345是一个八进制数字,赋值给c然后输出十进制,乍一看挺简单的,把345八进制数字转换十进制229就行了嘛,但是结果并非229.

为什么呢?因为八进制无法表示负数,从八进制转为十进制对于计算机来说并不是一个正确的方法。所以,按照计算机的运算方式,先将八进制转为二进制,从而看出是正数还是负数,再转为十进制输出。

(345)8 = (0 1110 0101)2

转换进制后,不要忘记char占1字节(8位),故最前面的0溢出了,即c的二进制是(1110 0101)2

这时最高位为1,表示这个数字是负数,要知道计算机保存一个负数是保存的是这个数字的补码,这里给大家普及一下原码、反码和补码内容。

例: 十进制 -12,求其二进制

  1. 得到12的二进制码,这个为原码

    (12)10 = (0000 1100)2

  2. 将原码按位取反,这个为反码

    ~(0000 1100)2 = (1111 0011)2

  3. 将反码+1,这个为补码

    (1111 0011)2 + 1 = (1111 0100)2

  4. 得到-12的二进制码

    (1111 0100)2

因此,只需将c二进制(1110 0101)2 按上面步骤反过来运输,就能得到正确答案了。

补码:(1110 0101)2

反码: (1110 0101)2 - 1 = (1110 0100)2

原码: ~(1110 0100)2 = (0001 1011)2

转10进制: (0001 1011)2 = (27)10

加上符号: -27

故答案为 -27

逻辑运算 1

1
2
3
4
5
6
7
8
9
10
11
//以下程序执行后的输出结果是 ____
#include <stdio.h>
void main() {
int a=5,b=4,c=3,d=2;
if(a>b>c)
printf("%d\n",d);
else if((c-1>=d)==1)
printf("%d\n",d+1);
else
printf("%d\n",d+2);
}

我们第一感觉就是a>b>c是真的,因为5>4>3嘛,所以会错写答案2。

但是,这里a>b>c是假的,为什么呢?其实,a>b>c 与 a>b && b>c 并不等价,a>b>c 与 (a>b)>c 才是等价的。

对于(a>b)>c,首先a>b为真,故为1,然后1>c为假,所以a>b>c为假。

对于a>b && b>c,首先a>b为真,为1,然后b>c为真,为1,计算1&&1,得到1,故a>b && b>c为真。

而(c-1>=d)==1就是相当于(c-1>=d),这个值为真

故答案是 3

逻辑运算 2

1
2
3
4
5
6
7
//以下程序执行后的输出结果是 ____
#include <stdio.h>
void main() {
int i=1,j=1,k=2;
if( (j++||k++)&&i++ )
printf("%d,%d,%d\n",i,j,k);
}

这个应该不算什么陷阱,主要理解而已。

对于j来说,其值已经是真了,故后面的k就不用运算了,此时 j=2,k=2

故答案为 2, 2, 2

前面两道题还是很有考验滴😂~

CATALOG
  1. 1. 进制转换、char占据字节、反码补码
  2. 2. 逻辑运算 1
  3. 3. 逻辑运算 2