计算机如何区分两条数据? [关闭]

Posted

技术标签:

【中文标题】计算机如何区分两条数据? [关闭]【英文标题】:How do computers differentiate 2 pieces of data? [closed] 【发布时间】:2012-05-05 07:46:51 【问题描述】:

我想知道计算机以 1 和 0/低压和高压的形式存储所有信息,yada yada...但是当我们编译程序时,它 - 或者只是存储在计算机上的任何数据 - 是以二进制形式...那么计算机如何区分 2 条数据,因为它只包含 0 和 1 的流...为了让我的问题更清楚,让我们从 C 中获取一个可笑的简单代码:

void main() 
    int A = 0;
    int* pA = &A;
    char c = 'c';
    char* pC = &c;
    return;

它什么也不做——只生成 4 个 int 类型的变量、指向 Int 的指针、char 和指向 Char 的指针...现在这些将以 0 和 1 的形式存储在某处...那么,如何计算机是否知道某个变量从哪个位开始以及在哪里结束?首先,您可能会说计算机有它的地址,好吧,当然。但是最后呢?......那么像对象/结构这样的复杂数据类型呢?

最后但并非最不重要的一点是,函数/程序呢?

【问题讨论】:

【参考方案1】:

编译后的程序将包含机器指令,这些指令以反映高级类型的模式访问数据。大多数汇编语言都有不同的指令来加载和操作不同大小(加载字节、字、长整数等)或类型(有符号和无符号整数、浮点数和长整数等)的数据。因为编译器在编译期间有可用的类型信息,所以它可以发出汇编指令,将内存中的数据(全都是零和一)视为具有适当的结构,方法是发出命令以一致的方式对数据进行操作使用类型系统。

对于结构和函数,有许多可能的编码取决于您使用的语言。去年夏天我教了一门编译器课程,我们花了两堂关于函数和对象布局的讲座。 slides for the first 和 second lectures 可在之前的链接中找到。

希望这会有所帮助!

【讨论】:

【参考方案2】:

它没有。相同的位序列可以解释为数字、字符串、代码、结构等等。计算机无法知道一堆比特的用途。

试试这个:

int main() 
    int A = 0;
    char* pC = (char*)&S;

你会发现它有效。它需要整数内存并说我想把它当作一个字符数组。计算机会很高兴地接受这一点。它很少有用,但可以做到。

不同类型的唯一不同之处在于它们的处理方式。浮点数的处理方式不同于整数的处理方式与字符串的处理方式不同。如果您查看程序的低级版本,您会发现包含的每个操作都特定于某种类型的数据。区别不在于位,而在于程序如何对位进行操作。

【讨论】:

【参考方案3】:

您可以通过尽可能接近金属来回答所有这些问题(以及许多更多关于计算机的问题):也就是说,学习组装。我建议阅读本书Art of Assembly(免费提供在线)也涵盖了这些主题。另外,请阅读我在Assembly learning resources上的回答。现在,让我简要回答您的问题:

1234563文件)。现在这意味着操作系统在某个地方有一个表,它可以跟踪每个程序在哪里存储了什么、什么是数据、什么是代码等。

基本层面的变量无非就是字节。现在,当你写一个语句比如

a = b + 1

编译器实际上为变量分配了一个任意地址,并将该地址硬编码(即写入实际常量,例如 0xA3F0)该地址到引用它的每个语句。

数据结构以许多不同的方式存储。但是,当谈到 c 结构时,事情就更简单了:如果我们忽略诸如填充之类的东西,它们只是一个接一个地存储该结构包含的变量。这就是为什么结构的长度总是已知的原因。

函数实际上是存储代码的内存位置。要“调用”函数,参数被加载到stack,或任何其他全局内存空间,然后跳转,即转到函数的地址被创建。当函数完成后,它会跳转到调用它的地址(地址也存储在堆栈中。)

重要的是要了解编译器会以上述方式完成所有繁重的代码翻译工作。高级语言所具有的所有功能都只是抽象,以使您的工作更轻松。然而最终它只是位和字节,0 和 1,5 伏和零伏。

更重要的是,现代架构不会让操作系统自己做所有这些事情。大部分的内务处理也发生在硬件级别,例如内存管理、标记内存地址用于什么目的等。

【讨论】:

感谢您提供这个稍微详细的答案...但恐怕您与“装配艺术”的链接似乎不起作用...无论如何,再次感谢!跨度> @ParthThakkar 很抱歉;我已修复它。似乎服务器出现故障,我发布它时正在运行。【参考方案4】:

您现在正在阅读的段落只不过是一串字母和标点符号。你怎么知道一个词在哪里开始和结束?你怎么知道这些词的意思?这个文本流如何传达有用的信息?

你可以对数学说同样的话。当您看到写在页面上的数学表达式时,它们只是一系列数字和符号,但它们是一种以紧凑形式传达深刻思想的强大方式。然后是音乐。点、旗和线的流如何代表音乐这样短暂的东西?

答案当然是有规则。这些字母不仅仅是随机组合的——它们有一个特定的顺序。当你遵循你和我都知道的规则时,你就能辨别单词,理解它们各自的含义,并将它们组合成思想。

二进制数据也是如此。将数据与随机位区分开来的是存在规则,如果遵循这些规则,则可以以有意义的方式解释位。现在,您已经提出了很多涉及各种规则的问题。试图解释它们会占用比这个答案更合理的空间(而且比我愿意投入的时间更多)。但是如果你拿起一本关于计算机体系结构的书,你会发现关于规则、它们如何工作、它们是如何组织以及它们是如何实现的完整讨论。真是有趣的东西!

如果您还没有准备好深入研究实际的计算机体系结构,一本可以让您深入了解的优秀书籍是道格拉斯·霍夫施塔特 (Douglas Hofstadter) 的Godel, Escher, Bach: An Eternal Golden Braid。这是一本厚厚的书,充满了思想。但它也写得很好而且很有趣,而且你不一定要从头到尾阅读它才能学到很多有趣的东西。

【讨论】:

【参考方案5】:

用高级语言编写语言规则,编译器将这些信息嵌入到创建的程序中。 cpu/处理器可能不太关心它只是位,它们除了在指令执行的很短的时间内没有任何意义。对于加法指令,位是加法或结果的操作数,对于加载或存储,它们可能是地址或地址的偏移量等,但在返回后立即成为无意义的位。

正如另一篇文章所述,您正在阅读的这些单词只是字母表中的字母组合,一次没有任何意义,对网络浏览器或显示像素的视频卡没有意义,但对高级别的意义用户,它们确实有意义。和程序一样,缩小一点,把程序看成一个整体,你会看到指令和位的组合形成了实现变量类型的程序序列和你编写和编译的高级程序序列。

没有魔法

【讨论】:

【参考方案6】:

电脑不知道,电脑也不在乎。它所做的只是按照说明进行操作。一条这样的指令可能会说:“从该地址获取 32 位,从该地址获取另外 32 位;使用称为‘二进制补码加法’的方法组合这两个 32 位字符串;并将结果存储在第一个 32 位中提到的地址”。每条指令都指定:

从中读取数据和写入数据的地址

读取或写入的位数

要对读取的位执行的操作

计算机并不关心操作是做什么的。只是计算机设计师足够优秀,让操作对我们人类有用。

像您提供的程序这样的程序在高级中是非常真实的。需要翻译才能产生计算机可以理解的形式。这样的翻译器知道int 是什么,int * 是什么,并且知道它们在内存中占用了多少位以及哪些计算机操作可以有效地应用于它们。

因此,您几乎回答了自己的问题:

首先,您可能会说计算机有它的地址,好吧,当然。但是结局呢?

知道起点和长度就知道终点。

更复杂的数据结构通常由单独的、更简单的部分组成。因此,在翻译此类代码时,您获取这些部分,为其分配偏移量,确保没有部分与另一个部分重叠,然后使用偏移量来计算用于访问这些部分的地址。

程序和功能太复杂,这里就不一一解释了。

但在最后有一个关于您的示例程序的简短说明。正如你所说,它没有任何作用。一个聪明的翻译器会简单地向计算机写一条“什么都不做”的指令。不太聪明的翻译器将为您声明的每个变量分配地址,并编写两条指令:“为这么多位保留空间;然后什么都不做”(位的数量是存储每个变量所需的空间长度)。计算机在任何时候都不需要知道您程序中的变量。

【讨论】:

我会不止一次赞成这个。这些 0 和 1 的含义是真正由人类直接或以他们编写的程序的形式赋予的。计算机什么都不知道,它只是执行人类编写的东西,接受对人类有意义的东西,并可能产生对人类有意义的结果,而不是对自己有意义的结果。它无法知道,也无法推理。所有的知识和推理都是由人类完成的。

以上是关于计算机如何区分两条数据? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何计算两条 ROC 曲线之间的 AUC 差异(95% CI)?

在图像分类中如何计算正确的标签? [关闭]

如何计算两条线的交点?

计算机组成原理~

如何区分虚拟化数据中心与云计算

组成原理~