不同类型的数据在内存中是如何存储的?

12

我正在编写一个涉及处理字节的C程序。在处理字节时,我对以下问题感到困惑:

  1. 字符是否按照它们的ASCII码存储在内存中?例如,'A'的ASCII码为65。因此,它被存储在内存中和整数65一样吗?

  2. 如果是这样,机器如何区分字符和整数?

  3. 如果字符按ASCII码存储,则ASCII码是一个整数。整数应该占用至少2个字节,那么为什么一个字符只占用1个字节?

  4. 最后一个问题是关于不同架构上的整数。在一个16位的机器上,如果1被存储为000...0001,那么在32位的机器上,1是否仍然以相同的方式存储,并在前面添加0?


机器不区分不同类型,C++编译器会区分。 - ApproachingDarknessFish
@ValekHalfHeart 编译器是否能通过声明类型区分它们的不同? - Xufeng
是的,这就是声明类型存在的原因。 - ApproachingDarknessFish
有关字符编码(UTF-8、UTF-16、UCS-2等)的讨论,请参见https://dev59.com/02gu5IYBdhLWcg3wv5ca。 - Richard Chambers
2个回答

12

字符是按照它们的ASCII码存储在内存中的吗?比如'A'的ASCII码是65。那么它和整数65以相同的方式存储在内存中吗?

是的,但在C语言中,char是一个字节,而int取决于机器架构。

如果是这样的话,机器如何区分字符和整数?

机器代码不关心内存中的字节表示什么。编译器的工作是将您的代码转换为执行程序所需的机器指令。

如果字符是按照ASCII码存储的,ASCII码就是一个整数。一个整数应该占用至少2个字节,那么为什么一个字符只占用1个字节?

ASCII可以放在一个字节中(即char的大小)。在C语言中处理非ASCII文本更加复杂。有一个非可移植的wchar_t,而且许多人认为它是有问题的。C11引入了char16_tchar32_t,分别用于UTF-16和UTF-32。

最后一个问题是关于不同架构上的整数。在16位机器上,如果1被存储为000...0001,那么在32位机器上,1是否仍然以相同的方式存储并在前面添加0?

这基本上是正确的,但也取决于endianness的架构。


1
比我写的更好措辞。 - keshlam
那么当存储'A'和65时,是65的前导0被忽略了而在'A'中保留了吗? - Xufeng
1
char a = 'A'char a = 65 其实没有任何区别。如果你问的是 int a = 65,那么是的,它多了几个0。 - imgx64
1
@imgx64:char a = 'A'char a = 65之间有区别。前者将a初始化为执行字符集中“A”的值,该字符集可能是ASCII,也可能不是。后者将a初始化为65。如果使用的是ASCII,则它们相同,但是有些C实现不使用ASCII。 - Eric Postpischil
2
@imgx64 我尝试打印 sizeof('A'),它给了我 4;但是 sizeof(char) 确实是 1。这是因为在 C 中 'A' 默认被存储为 int 吗? - Xufeng
@Xufeng 是的,字符字面量(例如 A)被编译器视为整数常量。 - imgx64

5
  1. 是的,ASCII字符会按照其值进行存储。但存储'A'(65 = 0x41)可能与存储65本身不同,这取决于您的机器架构。一个char可以用一个字节来存储,而int至少要占用2个字节(在现代计算机中通常为4个字节),因此它们可能被以不同的方式存储。

  2. 并不会。我们可以有等于0x41的内存。区分'A'和65的唯一方法是根据您如何向编译器声明变量。换句话说,如果您将变量声明为int,则它将被视为int。

  3. ASCII值非常少,您可以使用不到8位就能表示所有可能性。因此,使用16位来表示这一点将浪费内存。在今天的系统中,这已经不是问题了,但在内存受限制的系统上,您可能希望将那个额外的字节用于其他事情而不是浪费空间。

  4. 多或少而言,是的。1始终会以0000....1的形式存储,所以二进制数字的总数等于填满int的空间。因此,在8位系统上,它将是两个字中的00000000和00000001,在16位系统上,它将是一个字中的000000000000001。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接