数据类型究竟是如何在计算机中表示的?

wit*_*als 11 c types kr-c kernighan-and-ritchie

我是一名读K&R的初级程序员,我觉得这本书假定了很多以前的知识.令我困惑的一个方面是内存中变量的实际表示,或者我应该说存在.数据类型到底为变量指定了什么?我不太确定如何说出这个问题......但我会问几个问题,也许有人可以为我提出一个连贯的答案.

当使用getchar()时,我被告知使用类型"int"比键入"char"更好,因为"int"可以容纳更多值而"char"只能容纳256个值.由于我们可能需要变量来保存EOF值,因此我们需要超过256个,否则EOF值将与256个字符中的一个重叠.在我看来,我认为这是一堆空洞的盒子.有人能给我一个更好的代表吗?这些"盒子"有索引号吗?当EOF与256个可用值中的值重叠时,我们可以预测它将与哪个值重叠吗?

另外,这是否意味着数据类型"char"只能在我们简单地手动为变量赋值时使用,例如char c ='a',当我们肯定知道我们只有256个可能的ASCII时字符?

另外,"char"和"int"之间的实际重要区别是什么?如果我们可以使用"int"类型而不是"char"类型,为什么我们决定在某些时候使用一个而不是另一个?是保存"记忆"(我使用引号,因为我实际上并不是"记忆"究竟如何工作).

最后,char类型的256个可用值究竟是如何获得的?我读了一些关于modulo 2 ^ n的内容,其中n = 8,但为什么这样做(与二进制有关?).什么是"modulo 2 ^ n"的模数部分(如果它与模运算有任何相关性,我看不到关系......)?

jas*_*ord 10

好问题.K&R是在对计算机知之甚少的日子里写的,所以程序员对硬件知之甚多.每个程序员都应该熟悉这些东西,但是(可以理解)很多初学程序员都不熟悉.

在卡内基梅隆大学,他们开发了一个完整的课程来填补这个知识空白,我是TA.我推荐该课程的教科书:"计算机系统:程序员的视角" http://amzn.com/013034074X/

你的问题的答案比这里真正涵盖的要长,但我会给你一些简短的指导,供你自己研究.

基本上,计算机存储所有信息 - 无论是在内存(RAM)还是在磁盘上 - 二进制,基数为2的数字系统(与十进制相对,基数为10).一位二进制数字称为位.计算机倾向于使用称为字节的8位块内存.

C中的char是一个字节.int通常是四个字节(尽管在不同的机器上它可以是不同的).因此char只能容纳256个可能的值,即2 ^ 8.int可以容纳2 ^ 32个不同的值.

更多信息,请务必阅读本书,或阅读一些维基百科页面:

祝你好运!

按要求更新模块化算法的信息:

首先,阅读模块化算法:http://en.wikipedia.org/wiki/Modular_arithmetic

基本上,在二进制补码系统中,n位数实际上代表模2 ^ n的等价类.

如果这似乎使它变得更复杂而不是更少,那么关键的事情就是:

  • 无符号n位数保持0到2 ^ n-1的值.值"环绕",例如,当你添加两个数字并得到2 ^ n时,你真的得到零.(这称为"溢出".)
  • 带符号的n位数保持从-2 ^(n-1)到2 ^(n-1)-1的值.数字仍然环绕,但最高数字包围到最负数,并从那里开始向零计数.

因此,无符号字节(8位数)可以是0到255. 255 + 1包围到0. 255 + 2最终为1,依此类推.带符号的字节可以是-128到127. 127 + 1最终为-128.(!)127 + 2最终为-127等.


dan*_*ben 5

令我困惑的一个方面是内存中变量的实际表示,或者我应该说存在.数据类型到底为变量指定了什么?

在机器的水平之间的差异int,并char只有大小,或字节数,由编程语言分配给它的内存.在C,IIRC中,a char是一个字节,而a int是4个字节.如果您要"查看"机器内部的这些内容,您会看到每个机器的位序列.能够将它们视为intchar取决于语言如何解释它们(这也是为什么它可以在两种类型之间来回转换).

当使用getchar()时,我被告知使用类型"int"比键入"char"更好,因为"int"可以容纳更多值而"char"只能容纳256个值.

这是因为存在2 ^ 8或256个8位组合(因为一个位可以具有两个可能的值),而存在2 ^ 32个32位的组合.EOF常量(由C定义)是负值,不在0和255的范围内.如果您尝试将此负值分配给char(将其4个字节压缩为1),则高位将丢失,你将得到一个与EOF不同的有效char值.这就是为什么你需要将它存储到int中并在转换为char之前进行检查.

另外,这是否意味着数据类型"char"只能在我们简单地手动为变量赋值时使用,例如0char c ='a',当我们肯定知道我们只有256个可能的ASCII时字符?

是的,特别是因为在这种情况下你要分配一个字符文字.

另外,"char"和"int"之间的实际重要区别是什么?如果我们可以使用"int"类型而不是"char"类型,为什么我们决定在某些时候使用一个而不是另一个?

最重要的是,您可以选择intchar在语言级别,具体取决于您是要将变量视为数字还是字母(要切换,您需要转换为其他类型).如果你想要一个占用更少空间的整数值,你可以使用a short int(我相信是2个字节),或者如果你真的关心内存使用,你可以使用a char,尽管大多数情况下这不是必需的.

编辑:这是一个描述C中不同数据类型的链接和可以应用于它们的修饰符.有关尺寸和数值范围,请参见最后的表格.

  • 当然,但我仍然认为了解较低级别实际发生的情况很重要。 (2认同)
  • 在C中,`int`可以是4个字节,或更多,或更少.`int`必须能够表示`-32767`和`+ 32767`之间的值. (2认同)
  • int不是4个字节.所有C表示:short <= int <= long and short> = 2字节,long> = 4字节.参见K&R的"C编程语言",ANSI C版,第36页. (2认同)
  • 另外,在C中,`char`可以被签名,在这种情况下它*可以*存储`EOF`,但当然`char`也可以是无符号的,这就是我们在这种情况下使用`int`的原因. (2认同)

Mic*_*rdt 5

基本上,系统内存是一系列巨大的位,每个位都可以“打开”或“关闭”。剩下的就是约定和解释。

首先,没有办法直接访问各个位;相反,它们被分组为字节,通常以 8 个为一组(有一些外来系统并非如此,但您现在可以忽略它),并且每个字节都有一个内存地址。因此内存中的第一个字节的地址为 0,第二个字节的地址为 1,依此类推。

8 位字节有 2^8 个可能的不同值,可以解释为 0 到 255 之间的数字(无符号字节),或者解释为 -128 到 +127 之间的数字(有符号字节),或者解释为 ASCII 字符。每个 C 标准类型的变量的char大小为 1 个字节。

但字节对于很多东西来说太小了,因此定义了更大的其他类型(即它们由多个字节组成),并且 CPU 通过特殊的硬件构造支持这些不同的类型。如今, Anint通常为 4 个字节(尽管 C 标准没有指定它,并且整数在不同的系统上可以更小或更大),因为 4 个字节是 32 位,直到最近,这还是主流 CPU 支持的“字大小”。

所以一个类型的变量int有 4 个字节大。这意味着当它的内存地址为例如 1000 时,它实际上覆盖了地址 1000、1001、1002 和 1003 处的字节。在 C 中,也可以同时寻址这些单独的字节,这就是变量的方式可以重叠。

作为旁注,大多数系统要求较大的类型“字对齐”,即它们的地址必须是字大小的倍数,因为这使硬件变得更容易。因此,int 变量不可能从地址 999 或地址 17 开始(但 1000 和 16 都可以)。


Rob*_*lls 2

你好,

要深入了解,我强烈推荐 Charles Petzold 的优秀著作《代码

它涵盖的内容比您所要求的要多,所有这些都可以让您更好地了解幕后实际发生的情况。

华泰