数据模型介绍

文章探讨了计算机科学的核心是抽象和问题解决,通过数据模型来表达。数据模型包括静态的类型系统和动态的运算。C语言的数据模型详细阐述了其静态部分,如基本类型、数组、结构体、共用体和指针,以及动态部分的运算操作。文章还提到了数据模型在操作系统和应用程序中的应用,如文件系统和文本编辑器的数据模型。
摘要由CSDN通过智能技术生成

目录

计算机科学

数据模型

C语言数据模型


计算机科学

  从根本上讲,计算机科学是一门抽象的科学,它为人们思考问题以及找到适当的机械化技术解决问题而建立模型。

  计算机科学家必须抽象现实世界中的问题,使其既可以为计算机用户所理解,又可以在计算机内加以表示和操作。

  抽象意味着简化,是将现实中复杂而详细的情景替换为解决问题所使用的可理解模型。也就是说,我们将那些对解决问题而言影响甚微或根本没有影响的细节“抽象掉”了,从而建立一个让我们能处理问题实质的模型。

  通常情况下,找到好的抽象方式是相当困难的,因为计算机能执行的任务有限,执行速度也有限。要让计算机(或机器人)具有“智能”行为,就需要为计算机提供一个本质上跟人类所支配的世界一样详细的模型,不仅要包括事实(“萨莉的电话号码是555-1234”),还要包括原则和关系(“如果抛出某物体,它通常会向下坠落”)。

数据模型

  任何数学概念都可称为数据模型。而在计算机科学领域,数据模型通常包含以下两个方面。

  (1)对象可以采用的值。例如,很多数据模型包含具有整数值的对象。数据模型的这个方面是静态的,它告诉我们对象能接受哪些值。编程语言数据模型的这一静态部分通常被称为类型系统。

  类型系统用于定义如何将编程语言中的数值和表达式归类为许多不同的类型,如何操作这些类型,这些类型如何互相作用。类型可以确认一个值或者一组值具有特定的意义和目的(虽然某些类型,如抽象类型和函数类型,在程序运行中,可能不表示为值)

  (2)数据的运算。例如,我们常常会对整数执行加法这样的运算。模型的这一方面是动态的,它告诉我们改变值和创建新值的方式。


  每种编程语言都有自己的数据模型,这些数据模型互不相同,而且通常有相当大的差异。多数编程语言处理数据所遵循的基本原则是,每个程序都可以访问我们用于表示存储区域的“框”。每个框都具有一个类型,比如int或char。框中可以存储类型对应的值,通常将可以存储到这些框中的值称为数据对象。

  我们还要为这些框命名。一般来说,框的名称可以是任何指示该框的表述性词语。我们通常会将框的名称视作该程序的变量,不过情况并非完全如此。例如,如果x是递归函数F的局部变量,那么就可能会有很多名为x的框,每个x都与对F的不同调用相关联。这样的话,这种框的真实名称就是x与对F的某次调用的组合。

  C语言中的多数数据类型都是我们熟悉的:整数、浮点数、字符、数组、结构和指针。这些都是静态的概念。

  可以对数据进行的操作包括整数和浮点数的常规算术运算、数组或结构元素的存取操作,以及指针的解引用(也就是找到指针所指向的元素)。这些运算都只是C语言数据模型动态部分的一部分。


  数据模型不仅存在于编程语言中,而且存在于操作系统和应用程序中。操作系统的功能是管理和调度计算机的资源。像UNIX这样的操作系统,其数据模型具有文件、目录和进程这样的概念

  (1) 数据本身存储在文件中,在UNIX系统中,文件都是字符串和字符。

  (2) 文件被组织成目录(文件夹),目录就是文件和(或)其他目录的集合。目录和文件形成了树形结构,而文件处在树叶的位置。

  (3) 进程是指程序的独立执行。进程接受流作为输入,并产生流作为输出。

  文本编辑器中有另一种数据模型。文本编辑器的每种数据模型都结合了文本字符串的表示和对文本的编辑操作。

  这种数据模型通常会包含行的概念,行和多数文件一样,就是字符串。不过,与文件不同的是,行可能有着与其相关联的行号。行还可能被组织成更大的单元(比如段落),而且对行进行的操作通常适用于行内的任何位置,而不会像多数常见的文件操作那样,只是对前部进行操作。一般的文本编辑器会支持“当前”行(光标所在的那一行)的概念,还可能支持行内当前位置的概念。文本编辑器执行的操作包括对行的多种修改,比如在行内删除或插入字符、删除行,以及创建新行。在一般的文本编辑器中还可以在已编辑文件的行中搜索特定的字符串。

C语言数据模型

  首先介绍C语言数据模型的静态部分——类型系统,它描述了数据可能拥有的值。

  在C语言中,有着类型构成的无限集合,其中的任意元素都可以成为与某个特定变量相关联的类型。这些类型以及构成类型的规则就形成了C语言的类型系统。类型系统包含整数这样的基本类型以及一些类型构成规则(type-formation rule),利用这些规则,我们可以用已知的类型逐步构建更为复杂的类型。C语言的基本类型包括:

  (1) 字符(char、signed char、unsigned char);

  (2) 整数(int、short int、long int、unsigned);

  (3) 浮点数(float、double、long double);

  (4) 枚举(enum)。

  整数和浮点数称为算术类型。

  类型构成规则假设我们已经有了一些类型,可以是基本类型或使用这些规则构建好的其他类型。以下是C语言中的一些类型构成规则。

  (1)数组类型。可以用以下声明构建一个元素类型为T的数组:

  T A[n]

  该语句声明了包含n个元素的数组A,其中每个元素都是T类型的。在C语言中,数组下标是从0开始的,所以数组的第一个元素是A[0],而最后一个元素是A[n-1]。数组可由字符、算术类型、指针、结构体、共用体或其他数组构成。

  (2)结构体类型。在C语言中,结构体是由称为成员或字段的变量构成的分组。在结构体中,不同的成员可以具有不同的类型,但每个成员都必须具有某一个类型的元素。如果T1、T2、…、Tn是类型,而M1、M2、…、Mn是成员名称,那么如下声明

 struct S {
 T1 M1;
 T2 M2;
 …
 Tn Mn;
 }

  就定义了标记(即其类型的名称)为S而且具有n个成员的结构体。对i = 1、2、…、n来说,第i个成员名称为Mi,且其值为Ti类型。

  (3) 共用体类型。共用体类型允许一个变量在程序执行的不同时期具有不同的类型。

声明

 union{
 T1 M1;
 T2 M2;
 …
 Tn Mn;
 } x;

  定义了变量x,可以存放类型为T1、T2、…、Tn中任意一种的值。成员名称M1、M2、…、Mn用来指示x的值现在应该是哪种类型。也就是说,x.Mi就表明x的值是类型为Ti的值。

  (4) 指针类型。C语言的独特之处在于对指针的依赖。指针类型的变量包含某个存储区域的地址。可以通过指针,间接地访问另一个变量。声明

  T *p;

  定义了变量p是指向某个T类型变量的指针。用p来表示指向T的类型指针的框,框p的值就是个指针。我们往往将p的值表示成一个箭头,而不是将其表示成T类型的对象本身,如图所示。真正出现在p框中的是T类型对象在计算机中存储的地址(或位置)

  C语言的typedef结构可用来创建类型名称的同义字。


  函数也具有与之关联的类型,即使我们没有像处理程序变量那样,将框或“值”与函数相关联。对任意的一列类型T1、T2、…、Tn,我们可以定义一个函数,具有n个类型依次为这些类型的参数。这一列类型后面带上函数返回的值(返回值)的类型,就是这个函数的“类型”。如果函数没有返回值,那么该函数就是void类型的。一般情况下,可以应用类型构成规则任意地构建类型,不过也存在一些限制。比如,不能构建“函数数组”,不过构建由指向函数的指针构成的数组是可以的。


  C语言数据模型中的数据操作可分为以下三类。

  (1) 创建或销毁数据对象的操作。

  (2) 访问或修改数据对象某些部分的操作。

  (3) 将若干数据对象的值组合起来,为某个数据对象生成新值的操作。


  对于数据的创建,C语言提供了几种简陋的机制。在函数被调用时,会创建对应每个局部参数的框,这些框都用来存放参数的值。  另一种数据创建机制是使用程序库例程malloc(n),该例程可以返回一个指针,指向n个未使用的连续字符位置,这些存储空间可被malloc的调用者用来存储数据。然后就可以在这一存储区域中创建数据对象。

  C语言有着类似的方法来销毁数据对象。当函数返回时,该函数调用的局部参数将不复存在。例程free会释放malloc创建的存储空间。特别要说的是,调用free(p)的效果是释放p指向的存储区域。若使用free去销毁不是通过调用malloc创建的对象,会造成灾难性后果。

  C语言具有访问对象某些部分的机制。可以使用a[i]访问数组a的第i个元素,用x.m访问结构x的成员m,还可以用*p访问指针p指向的对象。在C语言中,修改(或者说是写)值主要是由赋值运算符完成的,这让我们可以改变对象的值。


  C语言有着丰富的运算符,可用来对值进行操作和组合。主要运算符包括如下这些。

  (1) 算术运算符。C语言提供了以下几种算术运算符。

    (a) 用于整数和浮点数的常规二元算术运算符、、*、/。整数除法会取整(4/3得1)。

    (b) 一元的和运算符。

    (c) 取模运算符i%j的结果是i除以j的余数。

    (d) 递增和递减运算符++和--,适用于单个整数变量反复从自身增加或减去1。这些运算符可以出现在它们的操作数之前,也可以出现在它们的操作数之后,取决于我们是想在改变变量的值之前还是之后计算该表达式的值。

  (2) 逻辑运算符。C语言中没有布尔类型,它使用“0”来表示逻辑值“假”,使用“非0”表示逻辑值“真”。①C语言使用以下几种逻辑运算符。

    (a) &&表示AND运算。例如,表达式x&&y在两个操作数都非0的情况下会返回1,否则返回0。不过,如果x的值为0,就不考虑y的值了。

    (b) ||表示OR运算。表达式x||y在x或y非0的情况下会返回1,否则返回0。不过,如果x的值非0,就不考虑y的值了。

    (c) 一元的否定运算符!x在x非0时返回0,在x=0时返回1。

    (d) 条件运算符是三元(三参数)运算符,用一个问号和一个冒号表示。表达式x?y:z在x为真(即x为非0)的情况下会返回y的值,在x为假(即x=0)的情况下会返回z的值。

  (3) 比较运算符。对整数或浮点数使用6种关系比较运算符之一(==、!=、<、>、<=、和>=),如果关系不成立,结果就为0,否则结果为1。

  (4) 位运算运算符。C语言提供了一些实用的位逻辑运算符,将整数当作与它们的二进制形式相同的位字符串。这些运算符包括,用于按位与的&,用于按位或的|,用于按位异或的^,用于左移位的<<,用于右移位的>>,以及用于左移位的波浪字符(~)。

  (5) 赋值运算符。C语言使用=作为赋值运算符。除此之外,还允许将x=x+y;这样的表达式写为x += y;这样的简短形式。类似的格式也可以用于其他二元算术运算符。

  (6) 强制转换运算符。强制转换是指将某个类型的值转换成另一个类型的等价值的过程。例如,如果x是浮点数,而i是整数,那么x = i会导致i的整数值被转换成值相等的浮点数。在这里,强制转换运算符并未显式出现,不过C语言编译器会推断从整数到浮点数的转换是必要的,并自动执行所需的转换步骤。    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值