深入理解计算机系统 (第 1 节)

1. c 语言之数组的越界访问 :

在这里插入图片描述

从上面的代码可以看到,在 c 语言里面,数组可以越界访问。但是越界到下标为 6 的时候为什么就不行了呢 ?(有趣但奇怪)

在这里插入图片描述

**从结构体 struct_t 来看,看 struct_t 在栈上开辟的空间,数组 a 和 double 类型的变量 d 是相邻的。double 是 8 个字节。下标为 4 和 5 的位置应该是没有人来使用的内存碎片,所以 fun(4) 和 fun(5) 都没有报错,但 fun(6) 就报错了,访问了别人的空间(非法访问) **

所以 c 语言的数组的这种变态访问也应该是 c 语言的不足,所以在 c++ 的 STL 模板的 vector 容器里面可以用 assert(下标的合理取值) 来直接检测下标的越界访问。因为这种情况在一些可能的情况下,可能出现很大的问题哦。

因为正如你所看到的那样,它不会执行边界检查,所以很容易编写出非法代码

2. c 语言诡异的二维数组赋值操作 :

在这里插入图片描述

上面是图片左边是一行一行进行赋值的(从 src 原数组赋值到目标数组 dst),有什么诡异的现象呢 ?

其实就是下面的赋值时间问题。

在这里插入图片描述

一行一行的访问,比一列一列的访问要好得多

3. & | ~ ^ 操作的国外理解 :

在这里插入图片描述

在这里插入图片描述

& :把两个二进制序列,下标都是 1 集合的进行 交集 的操作,就得到了结果数组在什么下标下是 1 的集合。

| :把两个二进制序列,下标都是 1 集合的进行 并集 的操作,就得到了结果数组在什么下标下是 1 的集合。
:这个是针对单一二进制序列的,1 变 0,0 变 1,就可以了,很好记忆和理解。

^ : 把两个二进制序列,下标都是 1 集合的进行 并集 - 交集 的操作,就得到了结果数组在什么下标下是 1 的集合。

4. 关于 signed 和 unsigned’ 类型的二进制序列转换十进制的计算 :

先要知道 singed 类型的第一位二进制是表示符号的,0 表示是正数,1 表示是负数。所以负数的个数比较正数的个数多一个,因为 0 不是正数也不是负数

singed : (0111)2 == (7)10, 7 = 2^2 + 2^1 + 2^0

​ (1111)2 == (-1)10, -1 = -1*2^3 + 2^2 + 2^1 + 2^0 (最高位的权重是 -2^n-1)

unsinged : (0111)2 == (7) 10

​ (1111)2 == (15)10, 15 = 1*2^3 + 2^2 + 2^1 + 2^0

再来一张图片来理解一下:

在这里插入图片描述

5. unsigned 在 c 语言里面是明确的诗句类型,在 java,python 里面不是哦:

所以在使用 unsinged 和 singed 的时候要考虑类型的转化,来看看吧(singed 和 unsinged 都有都情况下,一般是转换成 unsinged 类型了)

在这里插入图片描述

需要理解正数的 原码,反码,补码 都是一样的。负数的是不一样的。计算机存储的是补码

解释一下:-1 和 0U 哪一个大的问题。

-1 是有符号的 -1,补码是 1111 (也可以特殊记忆 -1,都是 1 的二进制序列,就是 -1。像 11,111,111111,…)。因为是和无符号的 0 进行比较,所以有符号的 -1 变成无符号的就变成了无符号里面当前二进制序列位数的最大值。肯定比较 0 大。

6. c 语言 signed 和 unsigned 的注意使用事项实例 :

for(unsigned i = n - 1; i >= 0; i--){
	fun(nums[i]);
}

// 上面的代码就会一直进行下去,直接死循环
// 因为 unsigned 的 i 肯定是 >= 0 的所以会死循环
for(int i = n - 1; sizeof(char) >= 0; i--){
	fun(nums[i]);
}

// 上面的代码也会死循环
// 因为 sizeof() 的返回值是 unsigned 类型的(注意哦)

7. 怎么保留二进制序列的最后 n 位 ? :

举个列子 :如果你只要保留二进制序列的最后 3 位,直接对 8 取模就可以了。因为对 8 取模的结果是 0 - 7 刚好可以用 3 位的二进制序列表示。

留二进制序列的最后 n 位 ? :

举个列子 :如果你只要保留二进制序列的最后 3 位,直接对 8 取模就可以了。因为对 8 取模的结果是 0 - 7 刚好可以用 3 位的二进制序列表示。

所以保留最后的 n 位应该也不成问题了吧。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值