计算机如何区分“ \ 0”(空字符)和“ unsigned int = 0”?


29

如果在给定的情况下,您有一个char数组(当然以null字符结尾),然后紧接着,在内存中的下一个位置,您想存储0为unsigned int,计算机如何区分这些字符?二?


18
您在询问典型答案正确的典型计算机。但是,曾经有一些使用标记内存来区分数据类型的体系结构。
grawity '18 -10-1

12
计算机无法以相同的方式将4字节的浮点数与4字节的整数区分开(代表一个非常不同的数字)。
哈根·冯·埃岑

6
虽然以0x00结尾的字符串很常见,但是有些语言使用长度前缀的字符串。第一个或两个字节将包含字符串中的字节数。这样,末尾不需要0x00。我似乎记得Pascal和BASIC这样做。也许还有COBOL。
点亮

@lit在许多通信协议中也是头格式。“您好,我是这种消息,我有那么多字节长”。通常,因为您需要在内部存储复杂的数据类型,所以空终止的解析变得更加麻烦。
mathreadler '18 -10-3

1
@lit:大多数Pascal和BASIC是的,和PL / I和Ada的变体-而在Java中,因为串共享在7u6下降有效地利用数组长度前缀-但仅COBOL排序的:你可以阅读从数据pic X occurs m to n depending on v(并且计数可以在任何地方,不仅是紧接之前),但存储起来更复杂。
dave_thompson_085 '18 -10-3

Answers:


86

没有。

字符串终止符是一个包含所有0位的字节。

unsigned int是两个或四个字节(取决于您的环境),每个字节包含所有0位。

两项存储在不同的地址。您编译的代码在前者的位置执行适合于字符串的操作,在后者的位置执行适合于无符号二进制数的操作。(除非您的代码中有错误或某些危险的聪明代码!)

但是所有这些字节在CPU上看起来都是相同的。内存中的数据(在大多数当前常见的指令集体系结构中)没有任何关联的类型。那是仅存在于源代码中的抽象,仅对编译器有意义。

编辑添加:作为示例:完全有可能,甚至很常见,对组成字符串的字节执行算术运算。如果您有一串8位ASCII字符,则可以通过添加或减去32(十进制)在字符串中的字母转换为大写和小写形式。或者,如果要转换为另一个字符代码,则可以将它们的值用作数组中的索引,该数组的元素提供其他代码中的等效位编码。

对于CPU来说,字符实际上是超短整数。(每位8位,而不是16位,32位或64位。)对我们来说,它们的值恰好与可读字符相关联,但CPU对此一无所知。它也对“空字节结束字符串”的“ C”约定一无所知(正如许多其他答案和评论所指出的那样,在编程环境中根本没有使用该约定) 。

可以肯定的是,x86 / x64中有一些指令经常与字符串一起使用-例如REP前缀-但是,如果它们能达到期望的结果,则也可以在整数数组上使用它们。


14
这就是开发人员必须谨慎对待字符串的原因。如果您有100个连续字节,则最多可以容纳99个1字节字符,最后一个字节中还包含终结符。如果在其中写入一个100字节的字符串,程序将无法确定该字符串在此处结束,并且将继续读取连续的字节,直到同时出现零字节为止。如果字符串长度超过100个字节,它将覆盖一些相邻的数据。高级编程语言(Java,C#,JS等)本身会自行处理,但是在C,C ++等低级语言中,汇编是开发人员的职责。
gronostaj

18
@gronostaj您的评论有点令人困惑:与C语言不同,C ++字符串也自动处理此问题。C ++通常也不会被归类为低级语言(甚至C有时也不会)。
康拉德·鲁道夫

5
有(旧的)CPU体系结构在数据值上都有类型标记,因此将整数解引用为指针将产生异常。
西蒙·里希特

8
@JamieHanrahan IA64处理器有一个叫做NaT(或“不是东西”)的位,如果设置了值,它会引发异常。
ErikF '18年

4
@KonradRudolph“自动”并不意味着“万无一失”,肯定不是在C ++中
rackandboneman 18/10/1

5

简而言之,没有区别(除了int的宽度为2或4个字节,而char仅为1)。

事实是,所有现代库都使用空终止符技术或存储字符串的长度。在这两种情况下,程序/计算机在读取空字符或读取的字符数与大小指示的字符数相同时,都知道它已到达字符串的末尾。

当缺少空终止符或长度错误时此问题就开始了,然后程序开始从不应有的内存中读取数据。


3
哦,简写有所不同-简而言之,简写是一种非常依赖于机器的数据类型,这是臭名昭著的:)
rackandboneman '18 -10-1

2

没有区别。机器代码(汇编器)没有变量类型,而是由指令确定数据的类型。

一个更好的示例是intand float,如果内存中有4个字节,则没有关于它是an int还是a float(或完全是其他东西)的信息,但是对于整数加法和浮点加法有2种不同的指令,因此如果整数加法指令用于数据,则它是整数,反之亦然。

与字符串相同,如果您有代码,例如,它查看一个地址并计数字节直到它到达一个\0字节,则可以将其视为计算字符串长度的函数。

当然,像这样的编程完全是疯狂的,所以这就是为什么我们有高级语言可以编译为机器代码,而几乎没有人直接在汇编器中编程。


2

科学的单字答案将是:元数据。

元数据告诉计算机某个位置的某些数据是整数,字符串,程序代码还是其他。此元数据可以是程序代码的一部分(如Jamie Hanrahan所述),也可以显式存储在某个地方。

现代CPU通常可以区分分配给程序代码的存储区域和数据区域(例如NX Bit https://en.wikipedia.org/wiki/NX_bit)。某些特殊的硬件也可以区分字符串和数字,是的。但是通常的情况是,软件会通过隐式元数据(在代码中)或显式元数据(面向对象的VM通常将元数据(类型/类信息)存储为数据(对象)的一部分)来解决此问题。 。

不区分不同类型的数据的优点是某些操作变得非常简单。I / O子系统不一定需要知道它刚刚从磁盘读取或写入磁盘的数据实际上是程序代码,人类可读的文本还是数字。所有这些都是通过机器传输的。让程序代码处理花哨的打字问题。


0

没有。你做吧!

或您的编译器/解释器。

如果说明告诉计算机将数字添加0为数字,它将执行该操作。如果他们告诉计算机在到达字符后停止打印数据,将其0作为' \0'字符,它将执行此操作。

语言具有确保如何处理数据的机制。在C变量具有类型,如intfloatchar,和编译器产生每个数据类型正确的指示。但是C允许您将数据从一个变量强制转换为另一个不同类型的变量,甚至可以将指针用作数字。对于计算机来说,所有其他方面都一样。


0

空字符是一个字节,无符号整数是两个字节。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.