csapp datalab

29 篇文章 0 订阅
28 篇文章 0 订阅

知识点总结

1. 逻辑运算符关系

and(与)、or(或)和xor(异或)是逻辑运算符,用于对布尔值进行操作。它们可以在不同的逻辑表达式之间进行转换。下面是and、or和xor之间的转换规则:

  • and转换为or: a and b = !(a or b) (取反)
  • or转换为and: a or b = !(a and b) (取反)
  • xor转换为and和or: a xor b = (a and !b) or (!a and b)

2. 补码

二进制补码(Two’s complement)是一种表示有符号整数的方法。它是计算机中常用的表示负数的方式。
在二进制补码表示中,最高位(最左边的位)被用作符号位,0表示正数,1表示负数。其余位表示数值的绝对值。
二进制补码的转换规则如下

  • 对于正数,其二进制补码就是其二进制表示本身。
  • 对于负数,首先需要将其绝对值转换为二进制表示,然后对其进行按位取反操作(即将0变为1,将1变为0),最后再加1。例如,对于十进制数-5,其二进制补码的转换步骤如下:将5转换为二进制表示:5 = 00000101,对二进制表示按位取反:11111010,将取反后的结果加1:11111011,所以,-5的二进制补码为11111011。
    在这里插入图片描述
    使用二进制补码表示有符号整数,可以方便地进行加法和减法运算,而无需特殊处理符号位。此外,二进制补码的表示范围也比使用其他方法表示负数更广泛。

补码范围:
补码是一种表示有符号整数的方法,它使用最高位作为符号位,0表示正数,1表示负数。补码的范围取决于使用的位数。
对于n位二进制补码表示,最小的补码整数是将最高位设置为1,其余位设置为0,最大的补码整数是将所有位都设置为1。
以8位二进制补码为例,最小的补码整数是:
10000000
这个二进制数的十进制表示是-128。
最大的补码整数是:
01111111
这个二进制数的十进制表示是127。
因此,8位二进制补码表示的范围是-128到127。
对于n位二进制补码,范围可以表示为-2 ^ (n-1) 到 2 ^ (n-1)-1。

3. int 获取负数

int类型的二进制表达式是用二进制数字表示一个整数。在C语言中,int类型通常是有符号的,因此它使用补码表示法来表示负数。

对于有符号的int类型,它占用固定的位数(通常是32位),其中最高位(最左边的一位)是符号位,用来表示正负。如果符号位为0,则表示该整数是正数;如果符号位为1,则表示该整数是负数。

以下是一个示例,展示了一个有符号32位int类型的二进制表达式:

00000000 00000000 00000000 00000000   // 0
00000000 00000000 00000000 00000001   // 1
00000000 00000000 00000000 00000010   // 2
...
01111111 11111111 11111111 11111110   // 2147483646
01111111 11111111 11111111 11111111   // 2147483647 (INT_MAX)
10000000 00000000 00000000 00000000   // -2147483648 (INT_MIN)
10000000 00000000 00000000 00000001   // -2147483647
10000000 00000000 00000000 00000010   // -2147483646
...
11111111 11111111 11111111 11111110   // -2
11111111 11111111 11111111 11111111   // -1

需要注意的是,整数的二进制表达式是从右向左排列的,最右边的一位是最低位,最左边的一位是最高位。每个二进制位表示一个权值,从右向左依次为1、2、4、8、16、32、64、128、256、…,以此类推。

对于无符号的int类型(即unsigned int),它也占用固定的位数(通常是32位),但没有符号位,因此可以表示更大的正整数。

以上是一个简单的示例,展示了int类型的二进制表达式。实际上,具体的二进制表达式可能会因编译器和平台的不同而有所不同。如果需要精确地了解某个特定编译器和平台上int类型的二进制表达式,可以使用位运算或相关的工具来查看。

简单来说就是 x 的负数就是 ~x+1

4. 判断字符是否是digit

在这里插入图片描述

5. 正数和负数的左移和右移

在C语言中,对于正数的左移操作和右移操作,补充的是零。
正数左移:

unsigned int x = 5;       // 二进制表示为 00000101
unsigned int result = x << 2;  // 左移2位,移动后的结果为 00010100,等于20

正数右移:

unsigned int x = 20;       // 二进制表示为 00010100
unsigned int result = x >> 2;  // 右移2位,移动后的结果为 00000101,等于5

负数右移:

int x = -20;       // 二进制表示为 11101100
int result = x >> 2;  // 右移2位, 移动后的结果为 11111011,等于-5

对于负数的左移操作,结果是未定义的。这是因为左移操作可能导致符号位发生改变,而C语言并没有明确规定负数左移的补充规则。因此,负数的左移操作是不可靠的,应该避免使用。

6. 负数使用逻辑非

这是因为非零的值在逻辑上被视为真,而逻辑非运算符将其取反得到假的结果。

int x = -10;
int result = !x;

// result 的值为 0

7. 逻辑取反运算符有两种形式:~ 和 !。

逻辑取反运算符有两种形式:~!

  1. ~ 运算符是按位取反运算符,用于对一个整数的二进制表示进行按位取反操作。它将每个二进制位的值进行翻转,即0变为1,1变为0。~ 运算符只适用于整数类型。

  2. ! 运算符是逻辑取反运算符,用于对一个表达式的逻辑值进行取反操作。如果表达式的值为真(非零),则 ! 运算符将其取反为假(0),如果表达式的值为假(0),则 ! 运算符将其取反为真(非零)。! 运算符适用于任何标量类型,包括整数、浮点数和指针类型。

以下是两种运算符的示例:

int x = 10;
int y = 0;
int result1 = ~x;  // result1 的值为 -11
int result2 = !y;  // result2 的值为 1

在上面的示例中,~x 对整数 x 进行按位取反操作,结果为 -11。而 !y 对整数 y 进行逻辑取反操作,因为 y 的值为0,所以结果为1。

8. 溢出问题

例如: int的范围是
01111111 11111111 11111111 11111111 // 2147483647 (INT_MAX)
10000000 00000000 00000000 00000000 // -2147483648 (INT_MIN) == 2 ^ 31
-2 ^ 31 - ( -2 ^ 31) 会出现溢出问题

9. 浮点数

浮点数编码是一种将浮点数值转换为二进制表示的过程。在计算机中,浮点数通常使用IEEE 754标准进行编码。

IEEE 754标准定义了两种浮点数表示格式:单精度(32位)和双精度(64位)。这两种格式都包括三个部分:符号位、指数位和尾数位。

符号位用于表示浮点数的正负性,占据了编码中的第一位。0表示正数,1表示负数。

指数位用于表示浮点数的指数部分,确定浮点数的大小范围。在单精度编码中,指数位占据了接下来的8位,而在双精度编码中,指数位占据了接下来的11位。

尾数位用于表示浮点数的小数部分,确定浮点数的精度。在单精度编码中,尾数位占据了接下来的23位,而在双精度编码中,尾数位占据了接下来的52位。

通过这种编码方式,浮点数可以以二进制形式存储和计算。然而,由于浮点数编码的特殊性,可能会出现精度损失和舍入误差等问题。因此,在进行浮点数计算时,需要注意这些问题可能带来的影响。

问题合集

1. makefile

在这里插入图片描述
删除m32:
使用gcc -m32编译的可执行文件无法在64位操作系统上运行。这是因为gcc -m32选项会将代码编译为32位的目标平台,生成的可执行文件只能在32位操作系统上运行。

在64位操作系统上运行32位可执行文件需要在系统上安装相应的32位库和运行环境。如果你尝试在64位操作系统上运行32位可执行文件,可能会遇到错误,例如缺少所需的库或不兼容的系统调用。

在这里插入图片描述

在这里插入图片描述

如果你希望在64位操作系统上运行代码,你应该使用默认的gcc命令来编译代码,而不是使用gcc -m32选项。这样将生成适用于64位目标平台的可执行文件。

2. c文件不是cpp文件

打印函数使用# include <stdio.h>

参考答案和解析

https://zhuanlan.zhihu.com/p/106109635

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值