五、程序语言的数据类型
作者:互联网
数据类型概述
- 定义:数据类型是一组数据对象及创建和操纵它们的操作集合所组成的类。每种程序设计语言都有自己特定的数据类型系统,通常都会为程序员提供基本的数据类型。而现代语言大都会提供给用户自定义新的数据类型的机制,用于表示结构化或抽象的数据类型,例如C++中为用户提供了自定义结构(struct)、联合(union)和类(class)的机制。
- 取值范围:一个数据类型中的所有元素构成了这个数据类型的定义域,即该数据类型的对象的取值范围。如果一个数据类型的定义域仅由常量值组成,则该数据类型就是标量类型,例如整型、实型、枚举类型都是标量类型。结构化数据类型和抽象数据类型的定义域中的元素都有自己的域,这些域又有自己的数据类型。
- 本节课程我们主要学习以下数据类型:
基本数据类型
- 概述:基本数据对象只有单一的数据值,这种对象及其上的操作的集合组成的类称为基本数据类型。
- 分类:
内建数据类型(Built—In)
- 定义:指程序设计语言提供的,无须用户另外定义的数据类型。各程序设计语言提供的内建数据类型都会有所不同,但通常都会提供整型、实型、布尔型、字符型4种内建数据类型。
- 根据属性分类:
1、数字数据类型:包括整形和实型,主要的操作有赋值操作、算术操作、关系操作(比较大小,返回布尔类型结果)和位操作。
2、布尔类型:定义域只有true和false两个对象。
3、字符类型:以单个字符作为其值的数据对象,例如ASCII字符集。
枚举类型
- 概述:我们经常会让一个变量只取少量几个值,如一周有7天,代表星期的变量就只会取7个值中的一个。虽然用整型数据对象可以表达该概念,但是程序员没法保证不对这些变量进行无意义的操作。枚举类型使程序员可以更好地定义和操作这些变量。
- 取值范围:枚举数据类型的取值范围是在列表中给出的,而在枚举数据对象上的运算为赋值和相等判定。
- 如一周的声明可以如下:
enum DayOfWeek {Monday,Tuesday,Wensday,Thursday,Friday,Saturday,Sunday}。
复合数据类型
- 主要有以下两种:
指针类型
- 概述:指针是一个数据对象在内存中的地址。指针变量实际上是用来存放某个数据对象的地址的变量。指针加上动态的数据对象的生成和对指针值的间接引用的机制,为程序员提供了处理可变大小的数据结构的机制。
- 指针类型的单个数据对象可以有两种处理方式:
1、仅能引用一种类型的数据对象:指针数据对象的值被限制为指向同一类型的数据对象。
2、可以引用任何类型的对象:这种方式允许指针数据对象在程序运行时指向多种类型的数据对象。 - 在某些语言中,指针是可以被程序操纵的数据对象,指针可以进行相加减操作,以指向当前数据对象后面(或前面)的某个数据对象。 而在另外一些语言中,指针是由语言实现管理的隐藏数据结构的一部分,通常被称为引用(reference)。
- 在指针上的操作有生成操作和选取操作:
1、生成搡作为固定大小的数据对象分配空间,同时生成一个指向新生成对象的指针,该指针存放在指针类型数据对象中。
2、选取操作允许沿着指针来访问指定的数据。
字符串类型
- 概述:字符串是由一个字符序列组成的数据对象。
- 字符串数据类型至少有以下3种不同的处理:
1、固定长度说明:字符串具有固定长度,并且在程序中加以声明。
2、指定上界的可变长度:字符串对象有一个最大长度,这个最大值可以在程序中定义, 而数据对象中的实际值的长度可能较短,甚至可以为零。
3、长度无限制:字符串数据对象可以是任意长度的字符串,字符串长度在运行过程中可以动态地变化。
说明:前两种的字符串处理方法可以在编译时确定,而第三种处理方法则需要在运行时动态地分配字符串存储。 - 对于字符串数据对象的操作,一般有连接、关系操作、使用定位下标选取子串、格式化、模式匹配和动态字符串。
结构化数据类型
- 概述:一个数据结构是一个包含其他数据对象作为其元素或成员的数据对象。
- 常见类型:
数组
- 概述:一个数组是包含固定数目的相同数据类型成员的数据结构。我们用数组名、数组元素的类型、维数及下标来刻画一个数组的特征。对于数组,成员数量常由下标范围序列隐式给出,数组中的每个成员都是单一数据类型,而数组的下标集通常由连续整数组成。
- 举例:
1、int a[10]; 说明整型数组a,有10个元素。
2、float b[10],c[20]; 说明实型数组b,有10个元素,实型数组c,有20个元素。 - 在给定下标值范围的语言中,下标范围不必从1开始,也不必是整数的范围,可能是枚举类型或枚举类型的子序列;
- 对数组的操作通常是使用下标进行成员的访问,这个操作称为下标标定,下标标定返回左值或者该成员代表的数据对象的位置。如果给出了数组成员的地址,取得数组成员的值就变成了一个简单的操作。
- C语言中,数组和指针的关系非常密切,常可以互换使用,例如上图所示:
记录
- 概述:一个由固定数目的不同类型元素组成的数据结构称为记录。记录和数组都是有固定长度的线性数据结构的数据类型。
- 记录与数组的不同之处在于:
1、记录的元素是可以异构的,即可以由不同类型的数据元素组成。
2、记录的元素使用标识符命名,而不是通过下标制定。
3、记录的属性有元素的个数、每个元素的数据类型和每个元素的选择符。记录的元素通常称为字段,元素的名称称为字段名。
4、记录的一个基本操作是元素选择,例如student.id。记录元素的选择是需要明确给出所选择元素的名称的。 - C语言提供的联合类型(union)就是这样的数据类型,在不同的情况下它可以存储不同类型的数据。
- 例如以下C语言中的声明:
union{
int i;
float f;
}u;
- 联合u既可以存储int类型数据,也可以存储float类型数据。我们可以把C语言中的联合看成一个特殊的结构,其中所有的成员相对于结构开始处的偏移量都为0,并且结构的存储量大得足够存储最大的成员。在任一时刻,我们只能访问联合中的一个成员。
列表和集合
- 列表:列表是由一连串有序的数据结构构成的数据结构,通常是不定长和异构的。在 LISP和Prolog等语言中,列表是基本数据对象。
- 列表的典型变形有:
1、堆栈(stack);
2、队列(queque)
3、树(tree);
4、有向图;
5、属性列表。 - 集合:集合是一种包含无序的不同值的数据对象,集合中的值是不能重复的。
抽象的数据类型
- 概述:1、数据对象的集合,一般使用一个或多个类型定义。2、在所定义的数据对象之上的抽象操作的集合。3、以上两个集合以如下规则封装起来:新的数据类型的使用者不能直接操作这种类型的数据对象,即该类型的使用者仅需要知道该类型的名字和可进行的操作的语义。
- 信息隐藏表示程序员定义的抽象设计中的原则:每一个这样的程序组件对于该组件的用户而言应该隐藏尽可能多的信息。当信息被封装在一个抽象中的时候,即意味着该抽象的用户无需知道所隐藏的信息即可使用该对象,且不允许他直接使用或操作隐藏的信息。 —个成功的抽象就是让用户无须了解该抽象数据类型定义的数据对象的具体表示和相应操作所使用的算法。
- 在C++语言中提供了类(class)这个新的定义抽象的数据类型的机制。C++语言通过访问存取控制关键字对成员的访问权限进行限制,它们分别是public、protected和private。为实现信息隐藏,通常会把成员数据的访问权限设置为protected或private。下面 是一个典型C++类的声明:
class stack{
private:
int a[100]={0};
int h=0;
public:
int pop();
void push(int item);
};
类型和错误检查概述
- 在程序设计中,最常用的数据对象是变量。程序语言需要确定变量是否应该具有固定的类型。 类型是对变量的一个约束,如果对变量类型的约束发生在程序运行前,即变量在程序中一旦声明为一种类型,即不能改变其类型的,我们称类型的约束为静态的,也称为早约束。 如果对变景类型的约束发生在程序运行时,即变量在程序中的类型是可以改变的,我们称为类型的约束为动态的,也称为迟约束。Pascal、C语言都是静态类型约束语言,Lisp和 Smalltalk则是动态类型约束语言。
- 进一步,我们可以把类型从单个的数据对象扩展至由数据对象和操作符组成的表达式。 表达式的类型应该在编译时就已知且为固定的。
- 一个语言的类型系统就是一组规则,这些规则为语言中的每个表达式关联一个类型, 如果一个表达式无法与某个类型相关联,那么类型系统就拒绝这个表达式。类型系统的规则也规定了每个运算符的正确使用。
类型检查的基本规则
- 类型系统中的规则基于函数的以下属性:从集合A到集合B的函数应用于集合A的元素,得到的结果是集合B的元素。
1、算术运算符:算术运算符是函数,对应每个运算符op都有一条规则规定如何由表达式E和F的类型确定表达式E op F的类型。
2、重载:运算符在不同的上下文中有不同的解释,可以接受不同类型的参数,并且可能根据参数的类型得到不同类型的结果,我们称为重载。常用的运算符,像+、-等都是重载的。例如 运算符+既可对整型进行加法运算,也可对实型进行加法运算。
3、隐式类型转换:当运算符需要的参数类型与实际参数类型不一致时,程序语言通常会在保证没有数据损失的前提下,自动地进行类型转换。例如C语言表达式23.14R中,R被声明为double类型,2是int类型,3.14是浮点类型,程序语言在不进行隐式类型转换的情况下无法确定 表达式的类型而必须拒绝此表达式。而在有隐式类型转换时,常数2和3.14都会被转换为double类型。进行运算后,结果也为double类型。
4、多态:多态函数具有参数化的类型,参数化类型也称为类属属性。多态类型允许只定义一次这类数据结构,以后可以应用到所需要的任何数据类型上。
类型等价
- 概述:类型等价是在程序语言的类型检查中必然会遇到的问题。类型等价一般可以分为以下两种:
- 1、结构等价:一个变量与自己结构等价;如果两个类型结构是对结构等价的类型应用相同类型构造符而形成的,则这两个结构等价;在type n=T (C语言中使用tepedef n T)声明下,n与T等价。
- 2、按名等价:
(1)纯名字等价:类型名与其自身等价,但结构化类型不与任何结构化类型等价;
(2)传递名字等价:类型名与其自身等价,且可以声明为与其他类型名等价;
(3)类型表达式等价:类型名仅与其自身等价,两个类型表达式等价,它们是从等价表达式应用相同的构造方式而形成的。
静态和动态类型检查
- 概述:类型检査是为了防止错误,保证程序中的运算应用都是正确的。如果某个函数或操作符接收到类型错误的参数,就会出现类型错误。如果程序执行中不会出现类型错误,则我们说它是类型安全的。
- 静态类型检査:在编译时,编译器通过类型系统规则,根据程序的源文本, 推断每次表达式f(a)求值时,参数的类型是否正确。
- 动态类型检査:把额外的检査代码加插到程序中,在程序运行时进行类型检查。因为需要加插代码,因此动态检查的效率不如静态检查高,并且潜藏在程序中的类型错误需要到运行时才会被检査出来。由于两者的差异,一般程序语言只检查在源程序中可以静态检查的属性,而对需要在运行时才能进行检查的属性则很少进行检査。
- 程序语言的类型系统还有“强”、“弱”的属性之分。这里的强弱是一个相对概念,是指类型系统防止错误的有效性。一个强类型系统仅接受类型安全的表达式,不是强的系统就成为弱的。
标签:对象,数据类型,等价,程序语言,类型,数据,指针 来源: https://blog.csdn.net/luoxuexi2020/article/details/117875891