320 likes | 440 Views
第四章 数组、指针. 教学目标 : 1 . 了解一维数组、二维数组的基本概念; 2 . 掌握数组类型变量的定义与引用 ; 3 . 掌握数组元素的引用 。 教学重点 : 1. 一维数组、二维数组的定义与引用; 2. 字符数组的定义与引用、常用字符串处理函数及 字符处理函数。 教学难点: 数组元素的引用 , 动态存储分配. 第四章 数组、指针. 4.1 数组 4.2 指针 4.3 动态存储分配. 4.1 数组的分类. 4 . 1 . 1 一维数组的定义与引用
E N D
第四章 数组、指针 • 教学目标: 1 .了解一维数组、二维数组的基本概念; 2 .掌握数组类型变量的定义与引用 ; 3 .掌握数组元素的引用 。 • 教学重点: 1. 一维数组、二维数组的定义与引用; 2. 字符数组的定义与引用、常用字符串处理函数及 字符处理函数。 • 教学难点: 数组元素的引用,动态存储分配
第四章 数组、指针 4.1 数组 4.2 指针 4.3 动态存储分配
4.1 数组的分类 4.1.1 一维数组的定义与引用 4.1.2 二维数组的定义与引用 4.1.3 字符数组与字符串类
4.1.1 数组的概念 1、定义 数组是在基本数据类型基础上构造出来的一种新的数据类型。 数组是具有一定顺序关系的若干相同类型变量的集合体,组 成数组的变量称为该数组的元素。 它的本质是把相同类型的一些变量有序汇集在一起,由同一 个名字、不同的下标来区分各个元素,从而为程序设计带来 便利。
2、声明与引用数组必须先声明,后使用。 • 一维数组的声明形式: 类型说明符 数组名[ 常量表达式 ]; 例如:int a[10]; 表示 a 为整型数组,有10个元素:a[0]...a[9] • 一维数组的使用形式(实质元素的引用) 数组名[ 下标 ] 下标:0->数组长度-1 说明:只能逐个引用数组元素, 而不能一次引用整个数组例如:a[0]=a[5]+a[7]-a[2*3] 下面用法是错误的: Int a[5],b[5]; a=b;//错误
a a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 数组元素在内存中顺次存放,它们的地址是连续的。 例如:具有10个元素的数组 a,在内存中的存放次序如下: 3、存储顺序 数组名是数组首元素的内存地址。 数组名是一个常量,不能被赋值。
在声明数组时对数组元素赋以初值。 例如int a[10]={0,1,2,3,4,5,6,7,8,9}; • 可以只给一部分元素赋初值,其它自动赋默认值。例如:int a[5]={10,20,30}; • 在对全部数组元素赋初值时,可以不指定数组长度。例如:int array[]= {10,20,30}; 4、初始化 5、举例 用冒泡法对n个数据按升序排序(由小到大)。 将n个数据两两进行比较,较大的数向后移动,经过一轮比较后,将最大的数移动到末尾。 下一轮再对剩下的n-1个数进行两两比较互换,得到次大数。如此进行多轮两两比较互换,最后得到一个由小到大的有序数组。
例如,对4个数据(9,8,7,2)的冒泡排序过程:例如,对4个数据(9,8,7,2)的冒泡排序过程: 9 8 8 8 8 9 7 7 7 7 9 2 2 2 2 9 排 序 第一轮 第二轮 第三轮 比较次数 3 2 1 结论:对n个数排序,要进行n-1轮,第i轮中要进行n-i次比较
#include <iostream> using namespace std; void main() { const int N=10; int i,j,t,a[N]; cout<<" Please input "<<N<< " numbers : "; for(i=0;i<N;i++) cin>>a[i]; //输入数组元素 cout<<" The numbers are : "; for(i=0;i<N;i++) cout<<a[i]<<‘\t’; //输出排序前的数组元素 cout<<endl;
for(i=1;i<=N-1;i++) //N-1轮 for(j=0;j<N-i;j++) //N-i次比较 if(a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t;//互换 } cout<<" The sorted numbers are : "; for(i=0;i<N;i++) cout<<a[i]<<‘\t’; cout<<endl; }
4.1.2一维数组的声明与引用 1、数据类型 标识符[常量表达式1][常量表达式2] …; 例: int a[5][3]; 表示a为整型二维数组,其中第一维有5个下标(0~4),第二维有3个下标(0~2),数组的元素个数为15,可以用于存放5行3列的整型数据表格。 注意:不能写成:int a[5,3]//错误
2、二维数组的声明 • 类型说明符 数组名[常量表达式][常量表达式] • 例如:float a[3][4]; • 3、存储顺序 按行存放,上例中数组a的存储顺序为: • 4、引用 例如:b[1][2]=a[2][3]/2 下标不要越界
5、初始化将所有数据写在一个{}内,按内存存放顺序赋值5、初始化将所有数据写在一个{}内,按内存存放顺序赋值 例如:int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; • 分行给二维数组赋初值 例如:int a[3][4] ={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; • 可以对部分元素赋初值 例如:int a[3][4]={{1},{0,6},{0,0,11}}; • 对全部元素赋初值时,定义数组时第一维的长度可省略 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};等价于 int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 或 int a[][4] ={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
6、有一个3X3的矩阵,分别求出两条对角线元素之和。#include <iostream> using namespace std; void main() { int a[3][3],i, j,sum1=0,sum2=0; cout<<“Please input 3x3 matrix:”; for(i=0;i<3;i++) for(j=0;j<3;j++) cin>>a[i][j] ; for(i=0;i<3;i++) { sum1+=a[i][i]; //主对角线 sum2+=a[i][2-i];//辅对角线 } cout<<“sum1=”<<sum1 <<“\nsum2=”<<sum2 <<endl; }
4.1.3 字符数组与字符串类 • 在一、二维数组的基础上,还可以推广到三维或更多维的数组。下面给出n维数组的定义: 数据类型 标识符[常量表达式1][常量表达式2] … [常量表达式n]; 例: int a[5][3][7]; //数组的元素个数是5*3*7=105 • 问n维数组的格式: a[0][0][0]=123; • 常用嵌套循环处理多维数组 for(i=0;i<5;i++) for (j=0;j<3;j++) for (k=0;k<7;k++) a[i][j][k]=1;
用字符数组存储和处理字符串 1、字符串常量(一般简称字符串) • 字符串常量,例如:“china“ • 字符串以‘\0’为结束标志,比较:“A”与‘A’ • C++语言没有字符串类型变量,用字符数组来存放字符串 • 字符串常量具有静态字符串类型数组 2、字符串类型(变量) C++语言没有字符串类型,但C++标准库有字符串类型string 头文件中加入 #include <string> using namespace std; 后就可以定义字符串类型变量 string name=“Tom”; //注意:string是一种用户自定义的数据//类型,如同使用C++语言基本类型一样 name是字符串变量
3、字符数组的定义:char类型的数组称为字符数组3、字符数组的定义:char类型的数组称为字符数组 • 如:char a[100]; • 4、字符数组使用特点 • (1) 可用字符串初始化字符数组,且数组长度至少要比字符串长度多1 • (2)整体使用字符数组的情况 • 使用字符数组名输出 • char str[8]="program"; • cout<<str; for(int i=0;i<8;i++) cout<<str[i]; • 使用字符数组名传递函数参数
例:字符数组的初始化与整体输出 • 方式一:用一维数组一般初始化方法 • char str1 [8]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,‘\0’}; • char str2[8]={112,114,111,103,114,97,109,0};//ASCII • 方式二:用字符串初始化字符数组 • char str3[8]=“program”;//数组长度至少要比字符串长度多1char str4[]="program"; • 字符数组的整体输出 • cout<<str4;
字符输入输出 • 方法: • 逐个字符输入输出 • 将整个字符串一次输入或输出例:char c[]="China"; cout<<c; • 注意: • 输出字符不包括 '\0' • 输出字符串时,输出项是字符数组名,输出时遇到'\0'结束。 • 输入多个字符串时,以空格分隔;输入单个字符串时其中 不能有空格。
4.2 指针 4.2.1 指针与地址的概念 4.2.2 指针变量的定义、初始化、运算 4.2.3 指针和数组 4.2.4 字符串的指针与指向字符串的指针变量
4.2.1 指针与地址的概念 • 指针是C++语言的重要概念,也是C++语言区别其他编程语言的显著特征之一。指针是指变量在内存中的存储地址,它可以使程序员直接对内存地址进行操作,可以明显地提高程序的运行速度,可以动态地分配内存空间,且可以实现复杂的数据结构等。在程序设计过程中,我们处理的数据大多数是以变量(对象)的形式出现,而每个变量都有两个最主要的属性—变量的内容和变量的地址。C++正是用指针来支持对变量地址的操作。
4.2.2 指针变量的定义、初始化、运算 • 与一般变量的定义相同,定义指针可以使用如下格式: • [〈存储类型〉]〈数据类型〉*〈标识符〉[=〈初值表达式〉]; • 其中,存储类型和初值表达式是可选的,“*”表示该变量为指针变量,标识符就是指针变量名,数据类型定义了指针可以指向的数据类型。例如: • int *ptrn; //定义了ptrn指向整型的指针变量 。Char *ptrc; //ptrc为指向字符类型的指针变量 • 没有赋初值的指针,其值是不确定的,它指向的地址空间有可能是非法的。因此在通过指针对数据进行操作之前,一定要对指针进行初始化。
有三种方法可用来定义指针变量 1. 先定义结构体类型再定义结构体变量 例:struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; struct student x1, x2; 类型标识符
2。 在定义指针类型的同时定义变量 • 形式定义 struct 结构体名 • { 成员表列} 变量名表列;例:struct student { int num; char name[20]; char sex; int age; char addr[30]; } x1, x2;
3 。 直接定义指针类型变量 定义形式 struct {成员表列} 变量名表列; 不出现结构体类型名
{ int num char name[20]; char sex; int age; char addr[30]; } x1, x2;
4.2.3 指针和数组 • 数组标识符代表数组中第一个元素的地址,它的类型是数组元素类型的指针。例如数组定义: • Int ia[]={o, 1,1,2,3,5,8,13,21}; • 那么只简单写 ia; • 意味着什么呢?在这个例子中ia的类型是int*,因此下面两种形式: ia; • &ia[0]; 是等价的,它们都返回数组第一个元素的地址。
4.2.4 字符串的指针与指向字 符串的指针变量 • C风格的字符串起于C语言,在C++中继续得到使用。指向C风格字符串的字符指针重视指向一个相关联的字符数组,即使当我们写一个字符串常量时,如: • const char *str=“The expense of spirit\n”; • 系统在内部也把字符串常量存储在一个字符串数组中,然后str指向该数组的第一个元素。 • Char*类型的指针被解引用,然后判断指向的字符是true 还是false(true值是除了空字符外的任意字符),++是增加运算符,它使指针指向数组中的下一个字符。
指向结构体变量的指针 • 用结构体变量和指向结构体变量的指针构成链表 struct LNode { int data; // 数据域 struct Lnode *next; // 指针域 } LNode;
4.3 动态内存分配 在C语言中是利用库函数malloc和free来分配和撤销内存空间的。C++提供了较简便而功能较强的运算符new和delete来取代malloc和free函数。 注意: new和delete是运算符,不是函数,因此执行效率高. new运算符的例子: new int; new int(100); new char[10]; float *p=new float(3.14159); 返回首地址,用户可以根据该指针的值(是否为空)判断分配空间是否成功
4.3 动态内存分配 delete运算符使用的一般格式为 delete [ ] 指针变量 例如要撤销上面用new开辟的存放单精度数的空间(上面第5个例子),应该用 delete p; 前面用“new char[10];”开辟的字符数组空间,如果把new返回的指针赋给了指针变量pt,则应该用以下形式的delete运算符撤销该空间: delete [] pt; //在指针变量前面加一对方括号,表示是对数组空间的操作
小结: • 理解数组的概念,掌握一、二维数组定义和使用方法 • 会用数组存储和处理字符串,了解String类 思考题: 编写程序将n个数按逆序输出 作业题: 用冒泡法对10个字符按降序排序 练习: 有如下结构: typedef struct {char m;string_node *next;}string_node 试利用这种结构存储字符串,并编制函数 search_max()能够在这个字符串中检索出出现次数最多的字符。