c语言中二维数组中维数的计算,数组指针字符串C语言程序设计-第4章.ppt

《数组指针字符串C语言程序设计-第4章.ppt》由会员分享,可在线阅读,更多相关《数组指针字符串C语言程序设计-第4章.ppt(132页珍藏版)》请在装配图网上搜索。

1、程序设计语言 (C) 王正杰 第四章 数组、指针与字符串 本章重点 数组的定义 、 初始化和使用;指针的 定义 、 访问和运算;指针与数组和函数的联系; 字符串与数组和指针的关系;结构体的应用; 几种常用的算法和数据结构 。 本章难点 指针的定义 、 赋值和运算;数组 、 字 符串 、 结构体的操作以及动态存储分配 。 在 C中 , 除了前面介绍的基本类型外 , 还有 一种用基本类型数据按一定的规则组成的构 造类型 , 构造类型的每一个分量可以是一个 简单的类型变量 , 也可以又是一个构造类型 的变量 , 它们可以像简单变量一样使用 。 C 语言的构造类型有数组 、 结构体 、 共同体等 。 。

2、指针是 C语言区别于其他程序设计语言的主 要特征 , 指针可用于有效的表示数据之间复 杂的逻辑关系 , 也可用于动态分配内存 , 还 可以简单有效地处理数组 。 用来存放字符串 的数组是字符数组 , 除了用访问数组的方式 来 操纵字符串外,我们还可以利用指针来使 用字符串。本章将介绍典型的构造类型 数组和结构体,以及与数组和结构体密 切相关的指针和字符串。 数组 是具有一定 顺序关系 的若干 相同类型 变量的集合体 ,组成数组的变量称为该数 组的 元素 。 一维数组通常用于表示由固定多个同类型 的具有线性次序关系的数据所构成的复合 数据,如向量、某个学生的各门课成绩、 学生的姓名表等。在语言中。

3、使用数组必 须先进行定义,一维数组的定义形式为: 存储类型说明符 数据类型标识符 数组名 常量表达式 ; int a5; 数组名是用户定义的数组标识符,数组名的 命名规则要遵循标识符命名规则。方括号中 的常量表达式表示数组元素的个数,也称为 数组的长度。 对于数组定义应注意以下几点: 1) 数组的 类型实际上是指 数组元素 的取值类型 。 对于 同一个数组 , 其所有元素的数据类型都是相 同的 。 2) 数组名不能与其它变量名相同 。 3) 不能在方括号中用变量来表示元素的个数 , 可以用符号常数或常量表达式 , 如 arrry10 表示数组 arrry有 10个元素 , 其下标从 0开始 。。

4、 一维数组的初始化 数组的初始化就是在定义的同时,给部分或 全部元素赋值,一维数组的初始化的格式是: 数据类型标识符 数组名 常量表达式 =初值 表 ; 其中,初值表用一对花括号 括起,每个初 始值之间用逗号隔开。例如: int array5= 1,2,3,4,5; 该语句定义了一个包含 5个整型元素的数组 array并对其进行了初始化,初始化后 array 0=1、 array1=2、 array2=3、 array3=4、 array4=5。 初值表元素的数量可以少于数组长度,也就 是可以只对数组的部分元素赋初值。例如: int array5=1,2,3; 初始化后前三个元素的值为 arr。

5、ay 0=1、 array1=2、 array2=3,其余没赋初值的 元素的值都为 0,即 array3=0、 array4=0。 也可以省略数组长度,例如: int array= 1,2,3,4,5; 初始化后数组的长度为 5。 一维数组的访问 像普通变量一样,数组定义之后,就可以 在程序中访问数组中的元素。我们只能逐 个访问其中的元素,对于数组元素的访问 可以通过以下形式表示:数组名 下标 int array5= 1,2,3,4,5; a=array3; array3=6; void main() int array5,i ; /使用循环语句对数组的 5个元素分别赋值 for (i=0; 。

6、i5; i+) arrayi=i*i; /分别输出数组元素的值 for (i=0; i5; i+) cout下标为 i的元素的值是: arrayiendl; C语言系统对数组的下标越界 不做任何检查 , 即对有 n个元素的数组 , 既可访问下标小于 0的元素 , 也可访问下标大于 n的元素 。 当 然 , 这样的元素是不存在的 , 所以越界访 问元素会给程序运行造成不可预测的后果 , 所以程序员应当自己控制下标越界的检查 。 用数组来处理求 Fibonacci数列问题 void main() int i; int f20=1,1; /初始化第 0、 1个数 for(i=2;i20;i+) fi。

7、=fi-2+fi-1; /求第 2 19个数 for(i=0;i20;i+) /输出,每行 5个数 if(i%5=0) coutendl; coutfi ; 向函数传递一维数组 当需要把一个一维数组传给一个函数时, 调用者需要把该一维数组的 变量名 以及数 组元素的个数传给被调函数,而被调函数 的形参应为不带数组大小的一维数组定义 以及数组元素的个数,下面我们通过一个 例子来了解向函数传递一维数组的过程。 int min ( int a, int length) int i,m=0; /m用于记录最小元的下标 for (i=1; ilength; i+) if(aiam) /逐个比较数组的元素。

8、 m=i; /找出最小的元素 return m; /函数 min将返回最小 /元素的下标: void main() int array10=18,26,23,13,15,25,27, 14,29,31,tag; tag=min(array,10); /调用函数 min,并将数组 /名作为参数传给函数 cout数组中最小的元素是: arraytagendl; 简单选择排序 假设排序过程中,待排记录序列的状态为: 有序序列 R1.i-1 无序序列 Ri.n 第 i 趟 简单选择排序 从中选出 关键字最小的记录 有序序列 R1.i 无序序列 Ri+1.n 对主调函数传递的数组进行排序 void so。

9、rt(int a,int length) /定义变量 tag以标记当前最小元素之下标, /定义交换变量 buffer int i,j,tag,buffer; for(i=0;ilength;i+) tag=i; /每次外循环,都将 tag的值置为 /内循环处理的第一个元素的下标 /内循环的任务是找出数组中下标 /从 i到 length的元素的最小者 for(j=i;jaj) tag=j; /标记小元素的下标 /将当前未排好序数组的最小元素 atag /和元素 ai交换 buffer=atag; atag=ai; ai=buffer; void main() int array10=6,2,10。

10、,3,7,5,9,4,8,1,i; coutendl排序前数组 array:; for(i=0;i10;i+)coutarrayi ; sort(array,10);/调用函数 sort,并将数组 array /和数组长度作为参数传递给函数 coutendl排序后数组 array为 :; for(i=0;i10;i+)coutarrayi“ ”; /输出排 序 /后的数组 array coutendl; 该程序使用的是选择排序 , 其思想是 , 第 一次从所有元素中选取最小值 , 与 a 0交 换;第二次从剩余元素中选取最小值 , 与 a 1交换; ;直至完成整个数组的排序 。 函数 sort。

11、中 , 每轮内循环结束后 tag中存放 的就是剩余元素中最小者的下标;第 i次外 循环结束后 , 数组前 i个元素就都是已经排 好序的元素 。 当排序完成返回主调函数 main后 , 主调函数的数组 array就是已经完 成排序的数组 , 这是因为 main函数中的数 组 array和 sort函数中的数组 a代表同一块存 储空间 , 从本质上讲它们是 同一个数组 。 用起泡法对 10个数排序 (由小到大 )。 起泡法的思路是:将相邻两个数比较,将 大的调到后头。 起泡排序 假设在排序过程中,记录序列 R0.n-1 的状态为: 第 i 趟起泡排序 无序序列 R1.n-i+1 有序序列 Rn-i。

12、+2.n n-i+1 无序序列 R1.n-i 有序序列 Rn-i+1.n 比较相邻记录,将 关 键字最大的记录 交换 到 n-i+1 的位置上 void main() int a10=6,2,10,3,7,5,9,4,8,1; int i,j,t; for(j=1;j10;j+)/此处的 j值表示末尾剩几个 for(i=0;iai+1) t=ai;ai=ai+1;ai+1=t; coutthe sorted numberS :endl; for(i=0;i10;i+) coutai ; 二维数组 前面介绍的数组只有一个下标 , 称为一维数 组 , 而在实际问题中经常要处理多维的量 , 需要构造。

13、二维数组或更多维的数组 。 简单地 说 , 二维数组就是具有两个下标的数组 , 其 元素有两个下标 , 以标识它在数组中的位置 。 数组维数的概念与几何中维数的概念是相似 的 , 如果说一维数组的元素是线性排列的 , 只要给出一个下标就可以确定某一特定元素 。 那么 , 二维数组就类似于几何中的 X-Y坐标 系 , 坐标系中只要指出 X坐标和 Y坐标就能 确定一个点 , 而要确定二维数组中的某一个 元素也只需指出元素所在的行和列 。 二维数组定义 存储类型说明符 数据类型标识符 数组名 常 量表达式 1常量表达式 2; 其中存储类型说明和数据类型说明与一维数 组相同,常量表达式 1表示第一维下。

14、标的长 度,常量表达式 2 表示第二维下标的长度, 两个常量表达式中不能包含变量。例如: int array23; 定义了一个二维数组 array,该数组有两行, 每行有三个元素。 二维数组的行下标和列下标都是从 0开始的, 对于 n行 m列的二维数组,行下标的取值范围 为 0n-1,列下标取值范围为 0m-1。 二维数组的所有元素占有的内存空间是连续的, 因此只要知道数组在内存中的起始地址就可以 很容易的算出其它元素的存储单元地址。 array00 array01 array02 array03 array04 array10 array11 array12 array13 array14 。

15、array20 array21 array22 array23 array24 array30 array31 array32 array33 array34 二维数组的初始化 二维数组赋初值的方式有两种,一种是不 分行给二维数组所有元素赋初值,比如 int array23=1,2,3,4,5,6;,另一种更直观的 方法是分行给二维数组所有元素赋初值, 如 int array23=1,2,3,4,5,6;。 同一维数组一样,二维数组也可以只给部分 元素赋初值,例如: int array23=1,2,3; 对数组前三个元素 array00、 array01、 array02分别赋以 1、 2、 。

16、3,其他剩余元素 都为 0。 此外二维数组还可以用分行的方法给部分元 素赋值,例如: int array23=0,2,4; 初始化后各元素的值是 array00=0、 array01=2、 array02=0、 array10=4、 array11=0、 array12=0, 对二维数组赋初值可以省略说明第一维的 长度,但是无论何种情况,都不能省略说 明第二维的长度。在给全部元素赋值时, 例如: int array23=1,2,3,4,5,6; 编译系统会根据初值个数分配相应的存储 单元。在分行给元素赋初值时,如: int array3=2,4,5,6; 编译系统也会根据所分的行数确定第一维 。

17、的长度。 二维数组的使用 对二维数组的访问同一维数组类似,也是通 过下标运算符“ ”和下标值来进行的。访问 的形式如下: 数组名 行下标 列下标 例如: int array23= 1,2,3,4,5,6; a=array10; array10=6; 这几条语句的功能是访问数组 array中,第二 行第一列的那个元素,将其值 4赋予变量 a后, 赋予其新值 6。 求 4*4二维数组各行和各列元素之 void main() int c4,r4, i,j; /定义 c4存放列元素的和, / r4存放行元素的和 int array44= 1,2,3,4,5,6,7,8, 9,10,11,12,13,1。

18、4,15,16; for(i=0;i4;i+) ri=ci=0; /初始化一维数组 . for(i=0;i4;i+) /输出行元素的和 cout“第” i+1“行元素的和为: riendl; for(i=0;i4;i+) /输出列元素的和 cout“第” i+1“列元素的和为: ciendl; for(i=0;i4;i+) for(j=0;j4;j+) /将第 i行第 j列的元素的值加入 ri ri=ri+arrayij; /将第 i行第 j列的元素的值加入 cj ci=ci+arrayji; /一次循环就好 /或 cj=cj+arrayij;多次循环才行 二维数组名作函数的参数 主函数中初始。

19、化一个矩阵并将每个元素都 输出,然后调用子函数,分别计算每一行 的元素之和,将和直接存放在每行的第一 个元素中,返回主函数之后输出各行元素 的和。 void RowSum(int A4, int nrow) int sum; for (int i = 0; i nrow; i+) sum = 0; for(int j = 0; j 4; j+) sum += Aij; cout Sum of row i is sum endl; Ai0=sum; void main(void) int i; int Table34 = 1,2,3,4,2,3,4,5,3,4,5,6; for (i = 0; 。

20、i 3; i+) for (int j = 0; j 4; j+) cout Tableij ; cout endl; RowSum(Table,3); for (i = 0; i 3; i+) cout Tablei0; 指 针 指针是 C+语言最主要的风格之一 , 也是 C+语言最重要的内容之一 , 利用指针变 量不仅可以有效地表示各种数据结构 , 也 可以用于参数传递和动态分配存储空间 , 并能象汇编语言一样处理内存地址 , 从而 编出精练而高效的程序 。 指针的应用使得 C+语言具有灵活 、 实用 、 高效的特点 。 在计算机中 , 所有的数据都是存放在存储 器中的 。 计算机的存储器。

21、就像一个巨大的 一维数组 , 每个数组元素就是一个存储单 元 。 一般把存储器中的一个字节称为一个 内存单元 , 不同的数据类型所占用的内存 单元数不等 , 如整型数据占 4个单元 , 字符 型数据占 1个单元 , 为了正确地访问这些内 存单元 , 必须为每个内存单元编上号 , 根 据一个内存单元的编号即可准确的找到该 内存单元 , 内存单元的编号也叫做地址 。 关于内存地址 内存空间的访问方式 通过变量名访问 通过地址访问 地址运算符: 则 int *p; /说明 p是一个指针变量,它的值 是某个整型变量的地址 float *q; /说明 q是指向浮点变量的指针变 量 char f ,*r;。

22、 /说明 f是字符变量, r是指向字 符变量的指针变量 指针的赋值 在定义一个指针的同时也可以对它进行初始化赋值, 通常是用一个与说明的指针具有 相同类型 的 变量的 地址 来进行赋值的。初始化赋值的形式如下: 数据类型说明符 *指针变量名 =地址 ; 其中地址可以是同类型变量的地址、数组的地址或 数组元素的地址。地址可以用取地址运算符 语句执行完后,变量 a的地址将赋给指针变量 p, 或称将指针 p指向变量 a 指针变量也可以在定义后赋值,如上述语 句就可以改为 int a=5, *p; p= 需要注意的是,没有赋值的指针变量中存 放的是一个随机值,使用没有赋过值的指 针是相当危险的。如果要。

23、使指针变量中的 指针不指向任何存储单元,那么可以将空 指针赋给指针变量,空指针的值为 0,也可 以用在 stdio.h中定义的符号常量 NULL表 示。 指针的访问 前面介绍的是如何对指针变量进行赋值,对 指针变量赋值后就可以对其进行访问了。 对指针值的访问有两种形式, 一种是将一个指针的值赋给另一个指针 另一种是用指针运算符 *将指针所指向的变 量的值取出用以访问。 void main() int a=10,b,*p= q=p; / 将一个指针的值赋给另一个指针 b=*q; /用指针运算符 *将指针 q所指向 /的变量的值取出并赋给 b coutb的值是: bendl; 以指针作为函数参数 。

24、以地址方式传递数据( 传入地址 ), 可以用来 带回 函数处理结果。 实参是数组名时形参可以是指针。 读入三个浮点数,将整数部分和 小数部分分别输出 void splitfloat(float x, int *intpart,float *fracpart) /形参 intpart、 fracpart是指针 *intpart = int(x); / 取 x的整数部分 *fracpart = x - *intpart; /取 x的小数部分 void main(void) int i, n; float x, f; cout Enter 1 floating point numbers x; sp。

25、litfloat(x, /变量地址做实参 cout Integer Part is n Fraction Part is f ab; pointer_1= pointer_2= cout输入的值分别是: a bendl; Swap(pointer_1,pointer_2); cout交换后的值分别是: a bq表示 p处于高地址位置; pq表示 p处于低地址位置 。 上述指针的关系 运算一般用于对数组的访问 。 指针变量加或减一个整数 i的意义是把指针 的当前位置 (指向某数组元素 )向前或向后移 动 i个位置。例如: short array8,*p; p=array; p=p+5; 其中第二。

26、条语句将指针 p指向数组 array即 指向 a0,第三条语句将 p指向 array5 设 p是指向数组 array的指针变量 , 则 p+i,p- i,p+,p-,p+=i等运算都是合法的 。 需要注 意的是 , 一个指针变量加 ( 减 ) 1并不是简 单地将原值加 ( 减 ) 1, 而是将该指针变量 的原值 ( 是一个地址 ) 和它指向的变量所占 用的内存单元字节数加 ( 减 ) 。 同样 , 指针 移动 i个位置不等于指针移动 i个字节 。 short *p; p+; 指针 p指向的地址向高地址移动了 2个字节 (因为一个短整型数占 2个字节 int *p; p+; 则指针 p指向的地址。

27、向高地址移动了 4个字节 两指针变量相减的得到一个整数。如果两 个指针变量指向同一个数组的元素,则两 个指针变量相减所得的整数是两个指针所 指数组元素之间相差的元素个数。例如: int array10,*p,*q,n; p=array; q=p+2;n=q-p; 其中第二条语句将指针 p指向数组 array即 指向 a0,第三条语句将 p指向 array2, 第四条语句将指针变量 q和 p相减得到的值 赋给变量 n,此时变量 n的值是 2。 指针与 0比较 指针变量可以与 0比较,例如: p=0表明 p 是空指针,它不指向任何变量; p!=0表示 p 不是空指针。需要再次强调的是,空指针不 同。

28、于未赋值指针,指针变量未赋值时,它的 值不确定,是不能使用的,否则将造成意外 错误。而指针变量赋 0值后,它就成为空指 针,它不指向具体的变量。 int *p; int b=*p;这里没有给 p赋值,就使用 *p,是 绝对错误的! 指针与数组 数组名是一个不允许赋值运算的指针,这个 指针的值就是数组的起始地址,例如,对整 型一维数组 array10, array就是一个指向 数组起始地址的指针,它指向数组的第一个 元素, array的值与 array0的地址相同 用 array+i可以表示 arrayi的地址,也就是 说 array+i与 pa= 或 pa=a; 通过指针引用数组元素 经过上述。

29、声明及赋值后: *pa就是 a0, *(pa+1)就是 a1, . , *(pa+i) 就是 ai. ai, *(pa+i), *(a+i), pai都是等效的。 不能写 a+,因为 a是数组首地址是常量。 设有一个 int型数组 a,有 10个元素。 用三种方法输出各元素: 使用数组名和下标 使用数组名和指针运算 使用指针变量 数组名和下标 for(i=0; i10; i+) coutai; 使用数组名指针运算 for(i=0; i10; i+) cout*(a+i); 使用指针变量 for(p=a; p(a+10); p+) coutij; coutaij=*(*(p+i)+j)endl;。

30、 多维数组的地址可作函数参数传递 在用指针变量作形参以接受实参数组名传 递来的地址时,有两种方法: 用指向变 量的指针变量 ; 用指向一维数组的指针变 量。 有一个班, 3个学生,各学 4门课,计算总 平均分数,以及第 n个学生的成绩。 用函数 average()求总平均成绩,用函数 search ()找出并输出第 i个学生的成绩。 void average(float *p,int n); void search(float (*p)4,int n); void main() float score34=65,67,70,60, 80,87,90,81,90,99,100,98; avera。

31、ge(*score,12);/求 12个分数的平均分 search(score,2); /求第 2个学生成绩 void average(float *p,int n) float *p_end; float sum=0,aver; p_end=p+n-1; for(;p=p_end;p+) sum=sum+(*p); aver=sum/n; coutaverage=averendl; void search(float (*p)4,int n) int i; coutthe score of No.n are: endl; for(i=0;i4;i+) cout*(*(p+n)+i) ; 指针。

32、数组 指针数组就是由指针组成的数组,也就是 说数组中的每个元素都是相同数据类型的 指针变量。指针数组的声明方式和普通数 组相似: 数据类型说明符 *数组名 常量表达式 ; 例如: char *pc5; 声明了一个一维指针数组,其中包括 5个元 素,均为指向字符类型的指针 void main() int line1=1,0,0; int line2=0,1,0; int line3=0,0,1; int *p_line3; /声明整型指针数组 p_line0=line1; /初始化指针数组元素 p_line1=line2; p_line2=line3; coutMatrix test:endl;。

33、 for(int i=0;i3;i+) /对指针数组元素循环 for(int j=0;j3;j+) /对矩阵每一行循环 coutp_lineij ; coutendl; 函数的指针 我们知道程序只有在代码装入内存后才能 运行,函数本身作为程序的一部分,也要 在内存中占有一片存储区域,这个区域的 起始地址,就是函数的指针,也称之为函 数的入口地址。函数的指针与数组的指针 类似,数组名代表数组的指针,即数组的 首地址,同样函数名就代表函数的指针, 也就是函数的入口地址。 函数原型为 int fun(int x,int y ,int z),则定义 函数指针变量的语句为 int(*pfun)(int,。

34、int,int), 需要注意的是,在声明指向函数的变量时, 变量名外的括号不能少。若是没有括号,如 int *pfun(int,int,int)就成为定义返回指针的函 数。 定义好的指针变量可以存放函数的指针,例 如: pfun=fun; 该函数返回值的数据类型,函数参数个数、 类型都应与定义指针变量时说明的一致 。 int minx(int x,int y) if(xy) return x; else return y; void main() int a,b,c; int (*pmin)(int x,int y); /定义指向函数的指针 pmin=minx; /将该指针指向函数 min /。

35、 可以写成 pmin= cout请输入第二个数: b; c=pmin(a,b); /通过函数指针调用函数 min /可以写成 (*pmin)(a,b) cout最小的数是: cendl; 返回指针值的函数 函数名前的数据类型标识符用于表示该函 数的返回值是什么类型的,函数的返回值 可以是整型、字符型或浮点型,也可以是 指针型,这时应该将函数的返回值说明成 相应数据类型的指针,返回指针值的函数 定义格式如下: 数据类型标识符 *函数名 ( 形式参数说 明列表 ) 其中数据类型标识符和函数名之间的 *表示 该函数的返回值是指针,数据类型标识符 表示指针指向的是何种类型的数据,例如: float *。

36、fun(int a , int b); 就声明了一个返回值为单精度浮点型指针 的函数。 float *compute(float x,float y) /定义 float型指针 result用以返回计算结果,并为 /其分配的空间(动态存储分配下一节将介绍) float *result=new float4; /将计算结果依次存入 result所指向的存储空间中 *result=x+y; *(result+1)=x-y; *(result+2)=x*y; *(result+3)=x/y; return result; /返回指针 result void main() float a,b,*p; 。

37、/定义 float型指针 p用以接受返回值 couta; coutb; p=compute(a,b);/调用函数, p和 result指向同一内存 if(p) /如果 result申请的空间得到了允许 /利用指针 p依次输出计算结果 cout两数的和是: *pendl; cout两数的差是: *(p+1)endl; cout两数的积是: *(p+2)endl; cout两数的商是: *(p+3)endl; delete p; /释放申请的内存空间 compute函数申请了 4个单精度浮点单元的 内存空间 , 并将这个空间的首地址赋给指 针变量 result, 计算的结果存放在这块存储 空间内 。

38、, 并将指针变量返回给主调函数 main。 主函数使用指针 p来接受 compute返 回的指针 result的值 , 再使用 p将计算结果 逐个输出 , 最后释放 p指向的内存空间 。 动态存储分配 到目前为止,程序中使用的变量和数组的类 型、数目和大小是在编写程序时由程序员确 定下来的,因此在程序运行时这些数据占用 的存储空间数也是一定的,这种存储分配方 法被称为静态存储分配,静态存储分配的缺 点是程序无法在运行时根据具体情况灵活调 整存储分配情况。 C+提供了内存空间动态 管理的机制,使程序在运行过程中可以按照 实际需要申请适量的内存,使用结束后,还 可以释放所申请的内存,在程序运行过程。

39、中 申请或释放的内存单元称为堆,动态申请和 释放内存的过程称作建立和删除。 自由存储区也称堆区 , 是一块可以动态管 理的内存区 , C+中用指针和 new运算符来 动态地申请一块内存单元 , 用 delete运算符 来释放被申请的内存单元 。 动态申请变量 空间与申请数组空间的格式略有不同 , 我 们分别进行讨论 。 使用 new运算符动态申请变量空间的格式如 下: new 数据类型标识符 ( 表达式 ) ; 数据类型标识符表示开辟的空间中存放何种 类型的数据,表达式表示对动态定义的变量 进行赋初值,可以省略。如果存储空间的动 态开辟成功,则返回指向那块开辟的内存单 元地址,否则返回 NUL。

40、L,即空指针。例如 : int *p; p=new int(2); 这两条语句的含义是,使用 new运算符从自 由存储区中分配一块与 int类型相适应的存储 空间,并赋初值 2,然后将这个存储空间的 首地址存入事先定义好的整型指针 p,如果 分配失败,则置指针 p为空指针 使用 new运算符动态申请一维连续空间格式: new 数据类型标识符 整型表达式 ; 其中,数据类型标识符表示要申请何种数据类 型的存储空间,整型表达式表示一维数组的长 度。如果申请分配成功,返回的是数组的指针, 失败则返回空指针 NULL 。需要注意的时候, 动态开辟数组时,无法对其中的元素进行初始 化。例如: int *。

41、parr; parr=new int 5; /申请的是长度为 5的整 型数组的存储区域 使用动态存储分配时要注意在确认分配成功后 才能使用,否则可能造成严重后果;分配成功 后最好不要变动指针的值,否则在释放这片存 储时会引起系统内存管理混乱;动态分配的存 储空间不会自动释放,只能通过 delete释放。 使用 delete运算符释放动态分配的变量和数组 存储空间的形式分别如下: delete p ; / delete 指针:释放变量空间 delete parr; / delete 指针:释放连续空间 编写程序时,动态的开辟内存一定要有相应的 内存释放,否则会造成内存空间的浪费。 输入任意个数的。

42、数据, 然后输出所有数据 void main() float *parr; /定义指针用来指向分配存储区的首地址 int i,length; /length用以记录要输入数据的个数 coutlength; parr=new floatlength; /申请长度为 length的 float数 组 if(parr) /如果内存分配成功,继续输入数据 else cout内存分配失败 endl; for(i=0;ilength;i+) cout请输入第 i+1parri; cout你刚才输入的数据是: endl; for(i=0;ilength;i+) coutparri ;/输出数组 couten。

43、dl; delete parr; /释放申请的内存空间 C语言编译系统的内存管理函数 void *malloc(unsigned int size); 其作用是在内存的动态存储区中分配一个 长度为 size的连续空间 。 此函数的值 (即 “ 返回值 ” )是一个指向分配域起始地址的 指针 (基类型为 void)。 如果此函数未能成功 地执行 (例如内存空间不足 ), 则返回空指针 (NULL)。 void free(void *p); 其作用是释放由 p指向的内存区,使这 部分内存区能被其他变量使用。 p是调 用 malloc函数时返回的值。 free函数无 返回值。 字 符 串 C+语言中。

44、的文字数据有两种:一种是单 个的字符,一种是字符串。在前面我们了 解到,单个的字符可以用字符变量存放。 C+中没有字符串数据类型,对字符串数 据的存放是通过字符数组或指针指向的一 块连续内存空间来实现的。 一维字符数组的定义和普通数组是类似的, 只不过数据类型标识符为 char型。如: char c10; / 定义了一个长度为 10的 一维字符数组 一维字符数组初始化的常用方式是以字符串 的形式进行初始化,即将整个字符串直接赋 值给数组。例如: char c10= “hello c+”;或者 char c10=“hello c+”; 也可以不指定数组长度进行赋值,例如: char c2= “h。

45、ello c+”; 字符串的结束标志 字符串总是以 0作为串的结束符 ,因此当 把一个字符串存入一个数组时,编译系统 会自动把结束符 0存入数组,并以此作为 该字符串是否结束的标志 二维字符数组 字符型的二维数组也可以看成由多个一维字符数 组组成的,所以可以用二维字符数组来存放多个 字符串。 char week3=“Sun”,”Mon”,”The”, ”wed”,”Thu”,”Fri”; 定义了一个 6行的二维字符数组 week,每行又可 以看作包含 3个元素的一维字符数组。注意,在 初始化时,元素是用双引号括起的,这是因为相 当于对一维字符数组赋予一个字符串作初值。 输入 ASCII码,查找。

46、并输出其对应的 大写英文字母 void main() char letter=ABCDEFGHIJKLMNOPQRSTUVWXYZ; int asc; /保存输入的十进制 ASCII编码 coutasc; if(asc=A /输出该编码对应字符 else cout该编码不是表示字符 endl; void main() int asc; coutasc; cout(char)ascendl; 指针访问字符串 对字符数组的访问同样也可以使用指针法, 所谓字符串的指针就是该字符串在内存中所 占空间的起始地址,由于字符串可以用字符 数组来实现,所以字符数组名就可以表示该 字符串的起始地址,即字符串的指。

47、针。我们 可以定义指针变量来存放字符串的指针。 char *string, c10=“hello c+”; string=c; 求字符串长度函数 int str_len(char str) char *p=str; /指针 p用以访问字符数组 str while(*p!=0) /当指针指向的单元 p+; /内容为 0时,表示字符串结束 return p-str; void main() char string=abcdefghijklmnopqrstuvwxyz; cout“字符串” string“的长度为: “ str_len(string)endl 例如使用字符串指针变量如 string可。

48、以进行 自加自减运算,而数组名 c不能进行自加、 自减运算;字符串指针变量的定义和初始 化可以同时进行,也可分开进行 char *string=”hello c+”; /字符串指针 变量的定义和初始化同时进行,正确 char *string; / 字符串指针变量先 定义,正确 string=”hello c+”; /字符串指针变量 后初始化,正确 字符数组的定义和初始化则只能同时进行, 不可以分开进行。 char c10=“hello c+”; /字符数组的定 义 /和初始化同时进行,正确 字符数组的定义和初始化分开进行 char c10; /字符数组先定义,正确 c=“hello c+”;/。

49、 字符数组后初始化,不正 确 字符串拷贝函数,将 str2内容拷入 str1 void str_cpy(char str1 , char str2) char *p1=str1,*p2=str2; int i=0; while(p2i!=0) p1i=p2i; i+; /指针使用下标 i完成移动 p1i=0; /必须给 str1补上结束标志 0 void main() char letter1=abcdefghijklmn, letter2=I love C+; cout字符串 letter2为: letter2endl; cout字符串 letter1为: letter1endl; str_。

50、cpy(letter1,letter2);/调用字符串拷贝函数 cout函数调用后字符串 letter2为: letter2endl; cout函数调用后字符串 letter1为: letter1endl; /输出完成拷贝的字符串 字符串处理函数 从前面的例子可以看到 , 用下标法和指针 法来操作字符串非常繁琐 。 因此 , C+提 供了一批用于字符串处理的库函数以完成 许多常用的字符串操作 , 如果要在程序中 调用输入输出的字符串函数 , 在使用前应 包含头文件 stdio.h, 使用其它字符串函 数则应包含头文件 string.h。 常用的两个字符串函数 strlen( str ) 功能:。

51、测字符串的实际长度 (不含字符串结束标志 0) strcpy (str1,str2) 把字符数组 str2中的字符 串拷贝到字符数组 str1中,串结束标志“ 0” 也一同拷贝。 结 构 在程序中往往还需要处理一些由不同类型元 素所构成的复合数据,例如学生基本信息的 数据,它由学号、姓名、专业号和入学成绩 等元素构成,这些元素不存在像数组那样的 线性关系,而且往往还具有不同的数据类型, 因此不能用数组类型来表示这样的数据。由 于这些数据元素之间有相当强的联系,如果 使用一些不同类型的变量来表示上述的复合 数据,就会破坏数据的内聚性,而且变量的 数目会变得很多,极大地降低程序的可读性。 C提供了。

52、结构类型用以描述和管理这种复杂 的数据结构 , 结构是若干相关数据项的有 机结合 , 但各数据项的数据类型可以不同 。 对于上例 , 可用 long型变量存放学号 、 char 型数组存放姓名 、 int型变量存放专业号 、 float型变量存放入学成绩 , 作为结构的成员 , 包含在结构类型中 , 再用该结构定义相应 的结构型变量 。 这样 , 学生的信息就可以 用一个结构型变量存放 , 数据之间的联系 得到了体现 , 数据的传递也大为方便 。 应以关键字 struct开始,结构类型名应符合标识符 命名规则,数据成员为结构中的数据项,它们都是 变量,其类型可以是基本数据类型,也可以是已定 义。

53、的自定义数据类型。成员名在结构体内具有唯一 性,但是允许成员名和程序中的变量名或是其他结 构体中的成员名重名,一个结构的所有成员应括在 一对花括号内,而且花括号后的 分号 是必需的。 struct student long num; char *name; int majornum; float scores; ; 定义结构体类型变量的方法 1. 先声明结构体,再定义变量名 (普遍使用 ) 如上面已定义了一个结构体类型 struct student, 可以用它来定义变量。如 : struct student student1, student2; 2. 在声明类型的同时定义变量 (不常用 ),。

54、例如: struct student student1 , student2; 3. 直接定义结构类型变量 (不常用 ) struct student1 , student2; 对结构变量的访问 有两种方式 一种是访问结构变量的某个数据成员, 另一种是访问整个结构变量。 访问一个结构变量中的某个数据成员需要用 到成员运算符“ .”,它是双目运算符,其左边 的操作数是一个结构类型变量,右边的操作 数是该结构的一个成员。例如, zhangsan.num表示访问结构类型变量 zhangsan的成员 num。结构类型变量的每个 成员都可以看作是一个独立的变量,对成员 变量可以实施像普通变量一样的操作。。

55、例如: zhangsan.num=20061001; zhangsan.majornum=10; 对整个结构变量的访问,赋值运算符 = 用于同类型变量之间的赋值操作,这个 过程实际上是整个结构变量值的复制过 程。例如, lisi=zhangsan; 就是将结构类型变量 zhangsan所有成员 的值复制给 lisi的相应成员变量。 结构体定义和变量的赋值与输出 struct student long num; char *name; int majornum; float scores; ; void main() /定义 student型变量 lisi、 wangwu、 a,初始化 lisi。

56、 student lisi=20061002, 李四 ,10,612,wangwu,a; wangwu.num=20061003; wangwu.name=王五 ; wangwu.majornum=10; wangwu.scores=607; cout 学号 姓名 专业号 入学成绩 endl; /分别输出 zangsan、 lisi的各个成员 coutlisi.num lisi.name lisi.majornum lisi.scoresendl; a=wangwu; /用 =将 wangwu的值复制给 a couta.num“ ”a.name “ a.majornum a.scores”。指。

57、向 运算符“ -”与成员运算符“ .”都是双目运算 符,而且它们优先级都是所有运算符当中 最高的,不同的是指向运算符“ -”左边的 操作数是结构指针,右边的操作数是该结 构的一个成员。第三条语句更多的是使用 指向运算符“ -”来完成: ps-num=20061001; 以线性表中第一个数据元素 的存 储地址 作为线性表的地址,称作线性表 的 头指针 。 1a 头结点 a1 a2 . a n 头指针 头指针 有时为了操作方便,在第一个结点之前 虚加一个“头结点”,以 指向头结点的 指针 为链表的头指针 。 空指针 线性表为空表时, 头结点的指针域为空 例如:逆位序输入 n 个数据元素的值, 建立。

58、带头结点的单链表。 操作步骤: 一、建立一个“空表”; 二、输入数据元素 an, 建立结点并插入; 三、输入数据元素 an-1, 建立结点并插入; an an an-1 四、依次类推,直至输入 a1为止。 带表头节点的单链表的基本操作 #define LEN sizeof(struct student) struct student long num; float score; struct student *next; ; struct student *creat(void) /此函数带回一个指向链表头的指针 int n=1; struct student *head; struct st。

59、udent *p1,*p2; head=( struct student*) malloc(LEN); /申请单元 */ head-next=NULL; p1=(struct student*)malloc(LEN); cout请输入第 n个学生的数据 p1-nump1-score; free(p1); return(head); while(p1-num!=0) p1-next=head-next; head-next=p1; p1=(struct student*)malloc(LEN); cout请输入第 n个学生的数据“ p1-nump1-score; void print1(struct student *head) coutNow, These records are: next; while (head) coutnum “ scorenext; main() struct student *head; /调用 creat函数后建立了一个单向动态链表 head=creat() ; print1(head); 插入操作 e ai-1 ai s p 删除操作 ai-1 ai ai+1 本章小结 数组是一个由若干同类型变量组成的集 合 , 它在内存中由连续存储单元组成 , 数组名本身就是指向这个起始地址的指 针 , 所以数组作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值