
第8章常用数据表达.ppt
46页第8章 常用数据表达 本章重点:本章重点: ● ● 常用的数据常用的数据类类类类型型● ● 宏的定宏的定义义义义与与应应应应用用● ● 数数组组组组的定的定义义义义和使和使用用● ● 指指针针针针的定的定义义义义和使和使用用● ● 构造体的定构造体的定义义义义● ● 枚枚举举举举与定与定义类义类义类义类 型型● ● 指指针针针针和数和数组组组组● ● 返回返回值为值为值为值为 指指针针针针的函数的函数● ● 指向函数的指指向函数的指针针针针根本数据根本数据类类类类型型类型类型基本类型基本类型 构造类型构造类型指针类型指针类型空类型空类型整型整型实型实型枚举型枚举型字符型字符型数组类型数组类型结构体类型结构体类型共用体类型共用体类型双精度双精度单精度单精度构造类型数据是由根构造类型数据是由根本类型数据按一定规本类型数据按一定规那么组成的,所以它那么组成的,所以它们又被称为们又被称为“ “导出类型导出类型〞§ §为为为为什么要有数什么要有数组这组这组这组这 么一个数么一个数据据类类类类型?型?§ §数数组组组组与其他根本的数据与其他根本的数据类类类类型型有什么区有什么区别别别别??8.1 8.1 数数组组组组 举例:一个班有举例:一个班有3030个学生,求这个学生,求这3030个学生的总成绩和个学生的总成绩和平均成绩。
平均成绩分析:假设按照我们以前的知识,涉及到分析:假设按照我们以前的知识,涉及到3030个学生的个学生的成绩,那么我们要定义成绩,那么我们要定义3030个变量来存储成绩信息个变量来存储成绩信息那么假设那么假设100100个学生呢?是不是要定义个学生呢?是不是要定义100100个变量?个变量?假设有假设有2 2万在校生,那么学籍管理系统中是不是要定万在校生,那么学籍管理系统中是不是要定义义2 2万个变量?万个变量?------------不可能!不可能! 如何表示这么多学生的相关信息〔例如成绩〕,如何表示这么多学生的相关信息〔例如成绩〕,就要引入数组的概念,数组是有序数据的集合数就要引入数组的概念,数组是有序数据的集合数组中的每一个元素都属于同一个数据类型可以用组中的每一个元素都属于同一个数据类型可以用一个统一的数组名和下标来惟一确实定数组中的元一个统一的数组名和下标来惟一确实定数组中的元素,利用循环来统一完成各个元素的各种操作素,利用循环来统一完成各个元素的各种操作数组具有如下主要特点:数组具有如下主要特点:〔〔1 1〕每个数组中的元素类型必须一致〕每个数组中的元素类型必须一致。
〔〔2 2〕用不同的下标来区分数组的元素〕用不同的下标来区分数组的元素〔〔3 3〕数组在内存中占有连续的存储单元,〕数组在内存中占有连续的存储单元,数组名表示数组在内存中的首地址数组名表示数组在内存中的首地址〔〔4 4〕数组和指针有着极亲密的联络,可以〕数组和指针有着极亲密的联络,可以通过指针挪动来对数组元素进展操作通过指针挪动来对数组元素进展操作#include
如:int n = 5;int a[n]; ③ 数组的下标从0开始如:a[10]下标是从0—9,而不是1--10下标可以是整型常量或整型常量表达式 ④ 和其他变量一样,数组也必须先定义后使用二、一维数组的引用、初始化与赋值二、一维数组的引用、初始化与赋值C C语言规定不能一次引用整个数组,引用时只语言规定不能一次引用整个数组,引用时只能对逐个元素进展引用能对逐个元素进展引用 (1) (1)一维数组引用:一维数组引用:引用形式:数组名引用形式:数组名[ [下标下标] ]注意:对下标的使用不要超过下标的最大值注意:对下标的使用不要超过下标的最大值尽管超过最大值时不出现编译错误尽管超过最大值时不出现编译错误但是运行的时候会出现杂乱的结果是运行的时候会出现杂乱的结果例如:例如:a[0]=8; a[2]=0; a[3]=2*a[2];a[0]=8; a[2]=0; a[3]=2*a[2]; (2)一维数组赋值如何给一维数组赋值呢?可以有三种方法: ①数组的初始化 ②程序中赋值 ③键盘中读入数组的初始化 在定义数组时对数组元素可赋以初值。
例如: static int a[10]={0, 1, 2,3 , 4, 5, 6, 7, 8, 9}; 初始化时可以只对一部分元素赋初值 例如: int a[10]={0,1,2,3,4}; 假设想使一个数组的元素值全部为0. 例如: static int a[10]={0}; 在对全部数组元素赋初值时,可以不指定数组长度 例如: int a[]={1,0,3,5,7}; ØØ程序中给数组的元素赋值程序中给数组的元素赋值例例8.2 8.2 程序中给数组的元素赋值,并输出数组元素的值程序中给数组的元素赋值,并输出数组元素的值 #include
出数组元素的值 #include
字符串虽虽虽虽然然C C语语语语言中没有字符串数据言中没有字符串数据类类类类型型,但却允,但却允许许许许使用字符串常量使用字符串常量§ § 在在C C语语语语言中,字符串是借助于字符型一言中,字符串是借助于字符型一维维维维数数组组组组来存放的,以字符来存放的,以字符‘\0’‘\0’作作为为为为字符串完字符串完毕标毕标毕标毕标 志志,它的,它的ASCIIASCII代代码值为码值为码值为码值为 0 0,,‘\0’‘\0’占用存占用存储储储储空空间间间间、不、不输输输输出,也不出,也不计计计计入串的入串的实际长实际长实际长实际长 度§ § 用字符数租存放字符串用字符数租存放字符串 8.1.2 8.1.2 字符数组字符数组char c[10];char c[10];c[0]=‘I’c[0]=‘I’;;c[1]=‘ ’;c[2]=‘a’;c[3]=‘m’;c[4]=‘ ’;c[1]=‘ ’;c[2]=‘a’;c[3]=‘m’;c[4]=‘ ’;c[5]=‘h’; [6]=‘a’;c[7]=‘p’;c[8]=‘p’;c[9]=‘y’;c[5]=‘h’; [6]=‘a’;c[7]=‘p’;c[8]=‘p’;c[9]=‘y’;§ § 字符数组的定义字符数组的定义字符数组的定义方法与普通的数组的定义字符数组的定义方法与普通的数组的定义方法类似。
方法类似a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]Iamhappy字符数组的输入输出字符数组的输入输出§ § 有以下方法:有以下方法:§ § 〔〔1 1〕逐个字符输入输出用格式符〕逐个字符输入输出用格式符"%c ""%c "输入输入或输出一个字符或输出一个字符§ § 〔〔2 2〕将整个字符串一次输入或输出用格式符〕将整个字符串一次输入或输出用格式符“%s“%s〞〞 ,对字符串进展输入输出对字符串进展输入输出§ § 〔〔3 3〕用〕用gets()gets()输入字符串,用输入字符串,用puts()puts()输出字符输出字符串例例8.4 8.4 利用字符数组,在终端中输出字符串利用字符数组,在终端中输出字符串“I “I Love Love China!China!〞 分析:初始化数组分析:初始化数组string[]string[],在初始化时直接用字,在初始化时直接用字符串常量,给字符数组符串常量,给字符数组string[]string[]赋值include
空格和其它字符的个数,并输出结果§ § 分析:用函数分析:用函数gets()gets()输入字符串,字符个数小于输入字符串,字符个数小于等于等于8080〔因为数组长度为〔因为数组长度为8080〕用gets()gets()函数输函数输入字符,可以输入空格,假设用入字符,可以输入空格,假设用scanf()scanf()函数输入函数输入字符,遇到空格时系统认为字符串完毕字符,遇到空格时系统认为字符串完毕§ § 设整型变量设整型变量letter , digit , space , otherletter , digit , space , other分别存放分别存放字母、数字、空格和其他字符的个数,其初始值字母、数字、空格和其他字符的个数,其初始值均为均为0 0在循环中判断数组中的每个字符是字母在循环中判断数组中的每个字符是字母〔那么〔那么letter++letter++〕?还是数字〔那么〕?还是数字〔那么digit++digit++〕?〕?还是空格〔那么还是空格〔那么space++space++〕?还是其他字符〔那〕?还是其他字符〔那么么other++other++〕?〕? #include
是一种特殊的一维数组二维数组中元二维数组中元素的排列顺序是:先按行存放,再按列素的排列顺序是:先按行存放,再按列存放,即在内存中先顺序存放第一行的存放,即在内存中先顺序存放第一行的元素,再存放第二行的元素元素,再存放第二行的元素 一、二维数组的定义一、二维数组的定义 定义格式:类型定义格式:类型 数组名数组名[ [行数行数][ ][列数列数] ];;〔〔1 1〕如:〕如:int a[2][3];int a[2][3];〔〔2 2〕在内存中,是按行存放的〕在内存中,是按行存放的〔〔3 3〕因为数组的存储是顺序的,所以,各个元素的〕因为数组的存储是顺序的,所以,各个元素的存储顺序为:存储顺序为: a[0][0] a[0][0] a[0][1] a[0][1] a[0][2] a[0][2] a[1][0] a[1][0] a[1][1] a[1][1] a[1][2] a[1][2]255914218300 0行:行: a[0][0] a[0][1] a[0][0] a[0][1] a[0][2]a[0][2]1 1行:行: a[1][0] a[1][1] a[1][0] a[1][1] a[1][2]a[1][2]三、二维数组元素的初始化三、二维数组元素的初始化 1. 1. 按行给二维数组赋初值。
按行给二维数组赋初值如:如:int aa[2][3]={{0,0,1},{1,0,0}};int aa[2][3]={{0,0,1},{1,0,0}};2. 2.也可以把数值写在一块:也可以把数值写在一块:int aa[2][3]={0,0,1,1,0,0}int aa[2][3]={0,0,1,1,0,0}那么那么aa[0][0]=0 aa[0][1]=0 aa[0][2]=1aa[0][0]=0 aa[0][1]=0 aa[0][2]=1aa[1][0]=1 aa[1][1]=0 aa[1][2]=0aa[1][0]=1 aa[1][1]=0 aa[1][2]=0 二、二维数组元素的引用二、二维数组元素的引用行号和列号都是从行号和列号都是从0 0开始的,并注意行号和列开始的,并注意行号和列号不要超过数组定义的范围号不要超过数组定义的范围3. 3. 假设初始化值比数组元素少,那么后面的假设初始化值比数组元素少,那么后面的元素值为元素值为0 0,,如:如:int a[4][5]={{1,2},{},{0,1,3}}int a[4][5]={{1,2},{},{0,1,3}}那么各值为:那么各值为: 1 2 0 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 0 0 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 4. 4. 可以对单个元素进展赋值:可以对单个元素进展赋值:aa[3][4]=5;aa[3][4]=5;5. 5. 假设对二维数组的所有元素都赋值,那假设对二维数组的所有元素都赋值,那么数组的第一维可以省略。
么数组的第一维可以省略 如:如:int m[][3]={1,2,3,4,5,6,7,8,9};int m[][3]={1,2,3,4,5,6,7,8,9}; 那么默认的第一维的值是那么默认的第一维的值是3 3 又如又如int m[][3]={1,2,3,4,5,6,7};int m[][3]={1,2,3,4,5,6,7}; 那么默认的第一维的值也是那么默认的第一维的值也是3 3;; 其中其中m[2][1]=m[2][2]=0; m[2][1]=m[2][2]=0; 例例8.6 8.6 二维数组输入、输出的例子二维数组输入、输出的例子 #include
假设是非对称矩阵,可以利用两个二维数组进交换假设是非对称矩阵,可以利用两个二维数组进展存储原矩阵和转置矩阵展存储原矩阵和转置矩阵#include
量 利用指利用指针针针针可以存放可以存放变变变变量的地址、数量的地址、数组组组组的地址的地址、函数的起始地址等,利用指、函数的起始地址等,利用指针针针针可以很方便地可以很方便地处处处处理数理数组组组组、字符串 计计计计算机的内存是以字算机的内存是以字节为单节为单节为单节为单 位的位的连续连续连续连续 存存储储储储空空间间间间,每一字,每一字节单节单节单节单 元都有一个元都有一个编编编编号,号,该编该编该编该编 号被称号被称为为为为地址,地址,这这这这个地址就像房个地址就像房间间间间号一号一样样样样在程序中在程序中定定义义义义的的变变变变量,在内存中都代表某一地址量,在内存中都代表某一地址8.3.1 8.3.1 指针变量的定义与赋值指针变量的定义与赋值〔一〕指针变量的定义〔一〕指针变量的定义一般形式:一般形式: 类型名类型名 * *指针变量名;指针变量名;例如:例如:int x ,*p1,*p2;int x ,*p1,*p2; 标志标志命名规那么同变量名命名规那么同变量名〔二〕指针变量的赋值〔二〕指针变量的赋值 可以初始化:类型名可以初始化:类型名 * *指针变量名指针变量名= =初值表达式;初值表达式; 例如:例如:int *px=&x;int *px=&x; 也可以赋值,例如:也可以赋值,例如: int x ,*p1,*p2; p1=&x; int x ,*p1,*p2; p1=&x;#include
用指针变量,输出普通变量的值指指针针针针运算符运算符例例8.9 8.9 指针变量的定义与相关运算例如指针变量的定义与相关运算例如include
元中 printf(“x=%d\n",x); printf(“x=%d\n",x);的的执执执执行行过过过过程,与程,与scanf()scanf()很相似:很相似: 首先找到首先找到变变变变量量x x的起始地址,然后从其地址中取出其的起始地址,然后从其地址中取出其值值值值,,最后将它最后将它输输输输出 〔〔2 2〕〕间间间间接接访问访问访问访问 ────通通过过过过另一另一变变变变量量访问该变访问该变访问该变访问该变 量的量的值值值值 CC语语语语言言规规规规定:在程序中可以定定:在程序中可以定义义义义一种特殊的一种特殊的变变变变量〔称量〔称为为为为指指针变针变针变针变 量〕,用来存放其它同量〕,用来存放其它同类类类类型型变变变变量的地址量的地址 int x=8 ,*p1; /* int x=8 ,*p1; /*定定义变义变义变义变 量量x,x,指指针变针变针变针变 量量p1*/ p1*/ p1=&x; /* p1=&x; /*指指针变针变针变针变 量量赋值赋值赋值赋值 */ */ printf(“%d,%d printf(“%d,%d〞〞,x,*p1); /*,x,*p1); /*输输输输出出*/ */8.3.2 8.3.2 指针变量的运算指针变量的运算 1. 1. 取地址运算取地址运算( (&&) )取地址运算的格式:取地址运算的格式: &变量&变量注意:指针变量只能存放指针〔地址〕,且只能是注意:指针变量只能存放指针〔地址〕,且只能是一样类型变量的地址。
一样类型变量的地址2. 2. 指针运算符〔指针运算符〔* *〕〕也称间接访问运算符用也称间接访问运算符用“*“*〞可以访问指针变量所〞可以访问指针变量所指向的变量的值例如:指向的变量的值例如:printf(“n=%d, printf(“n=%d, *pi=%d\n*pi=%d\n〞〞, , n, *pi);n, *pi);注意:指针标识符和指针运算符的区别在定义指注意:指针标识符和指针运算符的区别在定义指针变量时出现的指针变量名前的针变量时出现的指针变量名前的“*“*〞是一个标志,而在〞是一个标志,而在其余场合出现的其余场合出现的“*“*〞是运算符〞是运算符例例8.10 8.10 使用指针变量输入使用指针变量输入2 2个整数,按升序〔从个整数,按升序〔从小到大排序〕输出小到大排序〕输出include
指两个指针之间的元素个数〔〔4 4〕在一定条件下,两个指针可以比较〕在一定条件下,两个指针可以比较 当两个指针指向同一数组时,可以进展比较指向前当两个指针指向同一数组时,可以进展比较指向前面元素的指针小于指向后面元素的指针面元素的指针小于指向后面元素的指针 假设两指针不指向同一数组,那么两指针相减或比较假设两指针不指向同一数组,那么两指针相减或比较均无意义均无意义将一变量的地址赋将一变量的地址赋予指针变量予指针变量将一指针变量的值赋将一指针变量的值赋予另一指针变量予另一指针变量案例案例8.11 8.11 指针运算的实例分析程序输出的结果指针运算的实例分析程序输出的结果include
1. 1.指向数指向数组组组组的指的指针变针变针变针变 量的定量的定义义义义 指向数指向数组组组组的指的指针变针变针变针变 量的定量的定义义义义,与指向普通,与指向普通变变变变量的指量的指针针针针变变变变量的定量的定义义义义方法一方法一样样样样例如:例如:int array[10], *pointer;int array[10], *pointer; pointer pointer==array; /*array; /*或者或者pointerpointer==&array[0]; */&array[0]; */ 注意:数注意:数组组组组名代表数名代表数组组组组在内存中的起始地址〔与第在内存中的起始地址〔与第1 1个元个元素的地址一素的地址一样样样样〕,所以可以用数〕,所以可以用数组组组组名名给给给给指指针变针变针变针变 量量赋值赋值赋值赋值 2.2.数数组组组组元素的引用元素的引用 数数组组组组元素的引用,既可用下元素的引用,既可用下标标标标法,也可用指法,也可用指针针针针法法。
使用下使用下标标标标法,直法,直观观观观;而使用指;而使用指针针针针法,能使目的程法,能使目的程序占用内存少、运行速度快序占用内存少、运行速度快 int array[10], *pointer=array; int array[10], *pointer=array;那么:〔那么:〔1 1〕〕pointer+ipointer+i和和array+iarray+i都是数组元素都是数组元素array[i]array[i]的地址 〔〔2 2〕〕*(pointer+i)*(pointer+i)和和*(array+i)*(array+i)就是数组元素就是数组元素array[i]array[i] 〔〔3 3〕指向数组的指针变量,也可将其看作是数组〕指向数组的指针变量,也可将其看作是数组名,因此可按下标法来使用名,因此可按下标法来使用 例如,例如,pointer[i] pointer[i] 等价于等价于 *(pointer+i) *(pointer+i) 注意:注意:pointer+1pointer+1指向数组的下一个元素,而不是指向数组的下一个元素,而不是简单地使指针变量简单地使指针变量pointerpointer的值的值+1+1。
例例8.12 8.12 使用指向数组的指针变量来引用数组元素使用指向数组的指针变量来引用数组元素include
分析以下程序用指针输入输出数据分析以下程序,判断是否有错,假设有错,请找出错误原因,并改正,判断是否有错,假设有错,请找出错误原因,并改正include
量指向一个字符串 〔一〕字符串的表示与引用〔一〕字符串的表示与引用 在C在C语语语语言中,既可以用字符数言中,既可以用字符数组组组组存放字符串,存放字符串,也可用字符指也可用字符指针变针变针变针变 量来指向字符串;引用量来指向字符串;引用时时时时,既,既可以逐个字符引用,也可以整体引用可以逐个字符引用,也可以整体引用8.3.4 8.3.4 字符串与指针字符串与指针1. 1.逐个引用逐个引用例例8.14 8.14 使用字符指针变量指向和引用字符串使用字符指针变量指向和引用字符串include
〔〔1 1〕存〕存储储储储内容不同内容不同 字符指字符指针变针变针变针变 量中存量中存储储储储的是字符串的首地址,而字符的是字符串的首地址,而字符数数组组组组中存中存储储储储的是字符串本身〔数的是字符串本身〔数组组组组的每个元素存放一的每个元素存放一个字符〕个字符〕〔〔2 2〕〕赋值赋值赋值赋值 方式不同方式不同 对对对对字符指字符指针变针变针变针变 量,可采用下面的量,可采用下面的赋值语赋值语赋值语赋值语 句句赋值赋值赋值赋值 :: char *pointer; pointer=“This is a example. char *pointer; pointer=“This is a example.〞〞; /*; /*合法用法合法用法*/ */ 而字符数而字符数组组组组,,虽虽虽虽然可以在定然可以在定义时义时义时义时 初始化,但不能用初始化,但不能用赋值语赋值语赋值语赋值语 句整体句整体赋值赋值赋值赋值 下面的用法是非法的:下面的用法是非法的: char array[20] char array[20];;array=“This is a example.array=“This is a example.〞〞;/*;/*非法用法非法用法*/ */〔〔3 3〕指〕指针变针变针变针变 量的量的值值值值是可以改是可以改变变变变的,字符指的,字符指针变针变针变针变 量也量也不例外;而数不例外;而数组组组组名代表数名代表数组组组组的起始地址,是常量,而的起始地址,是常量,而常量不能被改常量不能被改变变变变。
1. 1.概念概念 数组的每个元素都是一个指针数据指针数组比数组的每个元素都是一个指针数据指针数组比较适宜用于指向多个字符串,使字符串处理更加方较适宜用于指向多个字符串,使字符串处理更加方便、灵敏便、灵敏 2. 2.定义格式定义格式 数据类型数据类型 * *数组名数组名[ [指针元素个数指针元素个数]; ]; 例如例如: int *p[5];: int *p[5]; char *str[7]; char *str[7]; 8.3.5 8.3.5 指针数组指针数组#include
数数组组组组指指针变针变针变针变 量量定定义义义义的一般形式的一般形式为为为为:: 类类类类型型说说说说明符明符 〔〔* *指指针变针变针变针变 量名〕量名〕[ [下下标标标标] ];;例如:例如:int a[2][3], (*p)[3];int a[2][3], (*p)[3]; p=a; p=a; 用用*(p[i]+j)*(p[i]+j)、、*(*(p+i)+j)*(*(p+i)+j)表示数表示数组组组组元素元素a[i][j]a[i][j]例8.16 利用数组指针,输出一个二维数组include
