The Wayback Machine - https://web.archive.org/web/20221028205936/https://baike.sogou.com/kexue/d10007.htm

数据类型

编辑
Python 3: 标准类型的层次结构

在计算机科学和计算机编程中,数据类型或简单类型是数据的属性,它告诉编译器或解释器,程序员打算如何使用数据。大多数编程语言支持实数、整数和布尔的通用数据类型。数据类型限制了表达式(如变量或函数)可能的取值。该数据类型定义了可以对数据进行的操作、数据的含义以及该类型值的存储方式。来自一个表达式的一类数据表示了表达式的取值。[1][2]

1 概念编辑

数据类型在类型系统中使用,类型系统提供了定义、实现和使用它们的各种方式。不同类型的系统确保不同程度的类型安全。

几乎所有编程语言都明确包含数据类型的概念,尽管不同的语言可能使用不同的术语。常见的数据类型包括:

  • 整数
  • 布尔值
  • 字符
  • 浮点数
  • 表示字母数字的字符串

例如,在Java编程语言中,int类型代表一组32位整数,其值范围从-2147483648到2147483648,以及可以对整数执行的操作,如加法、减法和乘法。另一方面,颜色由三个字节表示,分别表示红色、绿色和蓝色的数量,一个字符串表示该颜色的名称;允许的运算包括加法和减法,但不包括乘法。

大多数编程语言也允许程序员定义额外的数据类型,通常是通过组合其他类型的多个元素并定义新数据类型的有效操作。例如,程序员可能会创建一个名为“复数”的新数据类型,其中包括实部和虚部。数据类型也表示对类型系统中数据解释的约束,描述存储在计算机存储器中的值或对象的表示、解释和结构。类型系统使用数据类型信息来检查访问或操作数据的计算机程序的正确性。

统计数据中的大多数数据类型在计算机编程中具有对应的数据类型,反之亦然,如下表所示:

统计数字 编程语言
实值(区间标度) 浮点数
实值(比率标度)
计数数据(通常是非负数) 整数
二元数据 布尔型
分类数据 枚举类型
随机向量 列表或数组
随机矩阵 二维数组
随机树

2 定义编辑

(帕纳斯,肖尔和韦斯,1976)确定了文献中使用的“类型”的五个定义——有时是隐式的。包括行为在内的类型与面向对象模型更紧密地结合在一起,而结构化编程模型往往不包括代码,被称为简单的旧数据结构。

这五种类型是:

句法
类型是声明变量时与变量相关联的纯句法标签。这种“类型”的定义没有给类型赋予任何语义意义。
表示
一个类型是根据它更原始类型的组成来定义的——通常是机器类型。
代表性和行为
类型被定义为它的表示和操纵这些表示的一组运算符。
变量空间
类型是变量可以拥有的一组可能值。这样的定义使得谈论类型的(不相交的)并集或笛卡尔乘积成为可能。
变量空间和行为
类型是变量可以拥有的一组值和可以应用于这些值的一组函数。

表示的定义通常用命令式语言,如ALGOL和Pascal,而变量空间和行为的定义则用在高级语言,如Simula和CLU。

3 数据类型的类别编辑

3.1 原始数据类型

原始数据类型通常是内置的类型或语言实现的基本类型。

机器数据类型

基于数字电子技术的计算机中的所有数据以最低级别的位(0或1)表示。最小的可寻址数据单元通常是一组位,被称为一个字节(通常是八位字节,即8位)。由机器代码指令处理的单位称为一个字(截至2011年,通常为32或64位)。大多数指令将该字解释为二进制数,因此32位字可以表示取值范围从0到232-1的无符号整数值或表示取值范围从-231-1到231-1的有符号整数值。

  或来自的带符号整数值    

由于二进制补码,机器语言和机器在很大程度上不需要区分这些无符号和有符号的数据类型。

用于浮点运算的浮点数对一个字中的位使用不同的解释。

机器数据类型需要在系统或低级编程语言中公开或可用,允许在硬件上进行细粒度控制。例如,C语言提供各种宽度的整数类型,如短整型和长整型。如果目标平台上不存在相应的本地类型,编译器将使用现存的类型将它们在代码层进行分解。例如,如果在16位平台上请求32位整数,编译器会默认将其视为两个16位整数的数组。

在高级编程中,机器数据类型通常被隐藏或抽象为实现细节,如果显式表示,会使代码可移植性降低。例如,倾向于提供一个泛型数值类型,而不是某个特定位宽的整数。

布尔型

布尔型代表真值和假值。尽管只有两个值是可能的,但出于效率原因,它们很少被实现为单个二进制数字。许多编程语言没有显式布尔型,而是将0解释为假,将其他值解释为真。布尔数据是指如何将语言解释为机器语言的逻辑结构。在这种情况下,布尔值取0表示逻辑假。逻辑真总是一个非零值,尤其是一个取值为1的布尔值。

数字类型

例如:

  • 整数数据类型,或“非小数”。可以根据它们包含负值的能力进行子类型化(例如,在C和C++中无符号数)。也可以有少量预定义的子类型(如C/C++中的短整型和长整型);或者允许用户自由定义子范围,例如1..12(例如Pascal/Ada)。
  • 浮点数据类型通常将值表示为高精度的分数值(数学上的有理数),但有时被错误地称为实数(数学上的实数)。它们通常对最大值和精度都有预定义的限制。通常以a × 2b的形式存储在内部(其中a和b是整数),但以常见的小数形式表示。
  • 定点数据类型便于表示货币价值。它们通常在内部实现为整数,以实现预定义的限制。
  • Bignum或任意精度数字类型缺少预定义的限制。它们不是原始类型,出于效率的原因,它们使用得很少。

3.2 复合类型

复合类型派生自多个基本类型。这可以通过多种方式来实现。它们组合的方式被称为数据结构。将一个基本类型组合成一个复合类型通常会产生一个新类型,例如整型数组与整型是不同的类型。

  • 数组(也称为向量、列表或序列)存储许多元素,并提供对单个元素的随机访问。数组的元素通常(但不是在所有场景中)是同一类型的。数组可以是固定长度的,也可以是可变长度的。数组中的索引通常要求是特定范围内的整数(如果不是,可以通过关联数组来限制放宽的界限)(如果不是该范围内的所有索引都对应于元素,则可以是稀疏矩阵)。
  • 记录(也称为元组或结构)记录是最简单的数据结构。记录是一个包含其他值的值,通常是固定的数字和序列,并且通常由名称索引。记录的元素通常被称为字段或成员。
  • 联合体。联合类型定义将指定允许的基本类型中的哪一种可以存储在它的实例中,例如“浮点或长整数”。与记录相比,记录可以定义为包含一个浮点数和一个整数;然而,在一个联合体中,同一时刻只存在一种类型。
    • 标签联合(也称为变体、变体记录、区分并集或不相交并集)包含一个指示其当前类型的附加字段,以增强类型安全性。
  • 集合是一种抽象的数据结构,可以存储某些值,这些值没有任何特定的顺序,也互不重复。值本身不是从集合中检索的,而是测试成员资格值以获得布尔值“in”或“not in”。
  • 一个对象包含许多数据字段,如一条记录,还有许多用于访问或修改它们的子程序,称为方法。

还存在其他可能的数据类型,但是它们往往是上述数据类型的变体和组合。例如,链表可以存储与数组相同的数据,但是提供顺序访问而不是随机访问,并且由动态内存中的记录组成;尽管可以说链表类型是数据结构而不是类型本身,但它也足够常见和独特,因此将它包含在复合类型的讨论中是合理的。

枚举

枚举类型有不同的值,这些值可以比较和赋值,但不一定在计算机内存中有任何特定的具体表示;编译器和解释器可以任意表示它们。例如,一副扑克牌中的四套花色可以是名为CLUB、DIAMOND、HEART、SPADE的四个枚举数,属于名为花色的枚举类型。如果变量V被声明为适合它的数据类型,那么可以将这四个值中的任何一个赋值给它。一些实现允许程序员为枚举值分配整数值,或者甚至将它们视为与整数等价的类型。

字符串和文本类型

例如:

  • 表示字母和数字的字符。字母表中的字母、数字、空格、标点符号等。
  • 表示字母和数字的字符串,一系列字符。它们通常用于表示单词和文本。

字符和字符串类型可以存储字符集(如ASCII)中的字符序列。因为大多数字符集都包含数字,所以可能有一个数字字符串,如“1234”。然而,许多语言将这些视为属于和数值1234的不同的数据类型。

根据所需的字符“宽度”,字符和字符串类型可以有不同的子类型。最初的7位宽的ASCII被发现存在不足,并被8位和16位的集合所取代,这些集合可以编码各种各样的非拉丁字母(希伯来文、中文)和其他符号。字符串可以是可扩展长度的,也可以是固定大小的,即使是在相同的编程语言中。它们也可以根据最大尺寸进行细分。

注意:字符串不是在所有语言中都存在,例如在C语言中,它们是由一组字符组成的。

3.3 其他类型

类型是基于或派生于上面解释的基本类型。在某些语言中,如C语言,函数有一个从其返回值类型派生的类型。

指针和引用

主要的非复合派生类型是指针,这是一种数据类型,其值直接引用(或“指向”)计算机内存中使用其地址存储的另一个值。这是一种原始的引用。(在日常用语中,一本书的页码可以被认为是指另一个页码的数据)。指针通常以类似整数的格式存储;但是,试图取消引用或“查找”一个其值不是有效内存地址的指针会导致程序崩溃。为了改善这个潜在的问题,指针被认为其类型和它们所指向的数据类型完全不同,即使他们的底层表示是相同的。

功能类型

3.4 抽象数据类型

任何不指定实现的类型都是抽象数据类型。例如,堆栈(抽象类型)可以实现为数组(包含多个值的连续内存块)或链表(由指针链接的一组非连续内存块)。

抽象类型可以由不知道或“关心”其中包含什么底层类型的代码来处理。不知道具体数据类型的编程称为泛型编程。数组和记录也可以包含底层类型,但是被认为是具体的数据类型,因为它们指定了它们的内容或元素在内存中的布局。

例子包括:

  • 队列是先进先出的列表。变体是双端队列和优先级队列。
  • 一个集合可以存储某些值,没有任何特定的顺序,也没有重复的值。
  • 堆栈是后进先出的数据结构。
  • 树是一种层次结构。
  • 列表
  • 散列、字典、映射或关联数组是一种更灵活的记录变体,其中可以自由添加和删除名称-值对。
  • 智能指针是指针的抽象对应物。两者都是引用类型。

3.5 实用程序类型

为了方便起见,高级语言可以提供现成的“真实世界”数据类型,例如时间、日期、货币值和内存,即使语言允许由原始类型构建它们。

4 类型系统编辑

类型系统将类型与计算值相关联。通过检查这些值的数据流,类型系统试图证明不会发生类型错误。在问题中类型系统判定什么构成了类型错误,但是类型系统通常保证期望某类特定值不会和其他值构成一些无意义的操作。

编译器可以使用静态类型的值来优化它所需要的存储和对该值的操作算法的选择。例如,在许多C编译器中,浮点数据类型用32位表示,符合IEEE单精度浮点数规范。因此,它们将对这些值使用浮点专用微处理器操作(浮点加法、乘法等)。

类型约束的深度及其评估方式会影响语言的类型。考虑到多态的情形,编程语言可以进一步将操作与每种类型的不同具体算法相关联。类型理论是对类型系统的研究,尽管编程语言的具体类型系统源于计算机体系结构、编译器实现和语言设计的实际问题。

类型系统可以是静态或动态的,强或弱类型,等等。

参考文献

  • [1]

    ^本条目部分或全部内容出自以GFDL授权发布的《自由线上电脑词典》(FOLDOC)条目type。.

  • [2]

    ^Shaffer, C. A. (2011). Data Structures & Algorithm Analysis in C++ (3rd ed.). Mineola, NY: Dover. 1.2. ISBN 978-0-486-48582-9..

阅读 1.3w
版本记录
  • 暂无