(三)羽夏看C语言——进制

写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

你如果是从中间插过来看的,请仔细阅读 (一)羽夏看C语言——简述 ,方便学习本教程。

前篇答疑解惑

#include <iostream>
//如果是C,请自行将头文件包含改为 stdio.h 和 stdlib.h

int main()
{
    int i = 65534;
    int* pi = (int *)5;//这样对吗?
    unsigned char* pch = (unsigned char*)&i;
    printf_s("pch指向的地址存储的值:%d\n", *pch);//这样对吗?*pch的值到底是多少?
    system("pause");
    return 0;
}
  1. 答案:对。254。
  2. 解惑:指针也是变量,它可以被赋予任意值。由于小端存储,处于低字节的为0xFE,故pch指向的值为十进制的254。

什么是进制

  进制就是一种计数方式,简单地说几进制就是逢几进一。都是受过九年义务教育的同志,都掌握并熟练的运用十进制,可以用来进行加减乘除甚至更加复杂的运算。但是,这个世界上不仅仅有十进制,其他常见的有二进制八进制十六进制
  大家运算十进制的加减乘除,手算的话基本麻烦的用打草纸和笔运算,从来没听说十进制转成其他进制的再计算的。大学学过计算机都会经历过二进制或者十六进制转成十进制进行进一步计算的。
  虽然这样计算无可厚非,但这会破坏进制的完整性,每一个进制都是一个完整的体系。拿十六进制为例,为什么算加减生疏,因为练得少;为什么不会乘除,是因为小时候没背过十六进制的乘法表。说到这里并不是让面前的你学会手算十六进制,而是让你对进制有一个全面的了解。要不要计算器干嘛?😜

有符号与无符号

  对于有符号和无符号这东西,应该是困扰很多初学者的一个问题,它们到底有什么联系。在看下面的内容之前请自行把原码、反码、补码搞明白再回来看,这一块属于基础知识,本人概不手把手教这块内容。我们先来看下面的代码:

#include <iostream>
//如果是C,请自行将头文件包含改为 stdio.h 和 stdlib.h
//将 cout 改为 printf_s(可以 printf,但微软编译器编译会报错,自行科普)

using namespace std;

int main()
{
    unsigned int ua = 4294967295;
    int a = (int)ua;
    cout << "ua : " << ua << endl << "a : " << a << endl;
    system("pause");
    return 0;
}

  ua是无符号类型的变量,a是有符号且数值是从ua强转过来了,那么a的值是多少呢?
  结果是a的值是-1。这是为什么呢?
  在计算机中,整数运算采用补码,所有存储的都是无符号数,有无符号是对十进制数来说的。为什么这么说?我们计算机存储的数一般我们习惯用16进制来进行表示,而16进制是也没提有无符号的事情是不是?也就是说,我们存储的有无符号,仅仅是规定对某个16进制来如何解析出的10进制整数。
  说这东西你可能不太理解,我们来看看汇编代码:

int main()
{
004016D0  push        ebp  
004016D1  mov         ebp,esp  
004016D3  sub         esp,48h  
004016D6  push        ebx  
004016D7  push        esi  
004016D8  push        edi  
    unsigned int ua = 4294967295;
004016D9  mov         dword ptr [ua],0FFFFFFFFh  
    int a = (int)ua;
004016E0  mov         eax,dword ptr [ua]  
004016E3  mov         dword ptr [a],eax  
    cout << "ua : " << ua << endl << "a : " << a << endl;
……

  汇编代码我仅保留了关键部分,从上面的代码我们可以看出,我们所谓的强转只是将所谓的无符号数4294967295,十六进制为0xFFFFFFFF,周转到局部变量a,而这个是按照有符号进行解析,补码读取为-1,这就是为什么它的结果是-1
  最后我们总结一下:对于计算机来说,有无符号仅仅是十进制的说辞,是用来解析计算机存储数字的规则,有无符号仅仅是一个规则。

下一篇

  (四)羽夏看C语言——循环与跳转

posted @ 2021-09-02 15:50  寂静的羽夏  阅读(451)  评论(0编辑  收藏  举报