第四章 数组、指针 •教学目标 : 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 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;// 错误
3 、存储顺序数组元素在内存中顺次存放,它们的地址是连
续的。例如:具有 10 个元素的数组 a ,在内存
中的存放次序如下:
数组名是数组首元素的内存地址。数组名是一个常量,不能被赋值。
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]a[9]a
4 、初始化• 在声明数组时对数组元素赋以初值。 例如 int a[10]={0,1,2,3,4,5,6,7,8,9};
• 可以只给一部分元素赋初值,其它自动赋默认值。例如: int a[5]={10,20,30};
• 在对全部数组元素赋初值时,可以不指定数组长度。例如: int array[]= {10,20,30}; 5 、举例 用冒泡法对 n个数据按升序排序 (由小到大 )。将 n个数据两两进行比较,较大的数向后移动,经过一轮比较后,将最大的数移动到末尾。下一轮再对剩下的 n-1 个数进行两两比较互换,得到次大数。如此进行多轮两两比较互换 ,最后得到一个由小到大的有序数组。
例如,对 4 个数据( 9 , 8 , 7 , 2 )的冒泡排序过程:
9 8 8 88 9 7 77 7 9 22 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.24.1.2 一维数组的声明与引用一维数组的声明与引用
1 、数据类型 标识符 [常量表达式 1][ 常量表达式 2] …;例 : int a[5][3]; 表示 a 为整型二维数组,其中第一维有 5 个下标( 0~
4 ),第二维有 3个下标( 0~2 ),数组的元素个数为 15,可以用于存放 5行 3列的整型数据表格。注意:不能写成: int a[5,3]// 错误
• 3 、存储顺序按行存放,上例中数组 a的存储顺序为:
• 2 、二维数组的声明类型说明符 数组名 [常量表达式 ][常量表达式 ]例如: float a[3][4];
• 4 、引用例如: b[1][2]=a[2][3]/2
下标不要越界下标不要越界
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
; }
7 、将数组行列式互换。1 2
3
4 5
6
7 8
9
1 4
7
2 5
8
3 6
9
for (i=0; i<3; i++)
for (j=0; j<3; j++)
{ t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
for (i=0; i<3; i++)
for (j=0; j<i; j++)
{ t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
8 、打印杨辉三角形
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
void main(void)
{ static int n[2],i,j,k;
for(i=0;i<2;i++)
n[j++]=n[i]+i+1;
cout<<n[k]<<'\t'<<n[k++]<<endl;
}
2 1
4.1.3 4.1.3 字符数组与字符串类 字符数组与字符串类 • 在一、二维数组的基础上,还可以推广到三维或更多维的数组。
下面给出n维数组的定义: 数据类型 标识符 [常量表达式1][常量表达式2] … [常
量表达式 n]; 例 : int a[5][3][7]; // 数组的元素个数是 5*3*7=10
5• 问 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 类型的数组称为字符数组如: 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 指针指针4. 2. 1 指针与地址的概念4. 2. 2 指针变量的定义、初始化、运算4. 2. 3 指针和数组4. 2. 4 字符串的指针与指向字符串的指针变量
44 .. 22 .. 1 1 指针与地址的概念指针与地址的概念– 指针是 C++语言的重要概念,也是 C++语言区别其他编程语言的显著特征之一。指针是指变量在内存中的存储地址,它可以使程序员直接对内存地址进行操作,可以明显地提高程序的运行速度,可以动态地分配内存空间,且可以实现复杂的数据结构等。在程序设计过程中,我们处理的数据大多数是以变量(对象)的形式出现,而每个变量都有两个最主要的属性—变量的内容和变量的地址。 C++正是用指针来支持对变量地址的操作。
44.. 22.. 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; 类型标识符struct student x1, x2; 类型标识符
2 。 在定义指针类型的同时定义变量
• 形式定义 struct 结构体名• {
成员表列 } 变量名表列;例: struct student
{ int num; char name[20]; char sex; int age; char addr[30]; } x1, x2;
• 形式定义 struct 结构体名• {
成员表列 } 变量名表列;例: struct student
{ int num; char name[20]; char sex; int age; char addr[30]; } x1, x2;
3 。 直接定义指针类型变量
定义形式 struct
{ 成员表列 } 变量名表列;不出现结构体类型名
定义形式 struct
{ 成员表列 } 变量名表列;不出现结构体类型名
{ int num
char name[20];
char sex;
int age;
char addr[30];
} x1, x2;
44 .. 22 .. 3 3 指针和数组指针和数组• 数组标识符代表数组中第一个元素的地址,它的类型是数
组元素类型的指针。例如数组定义:• Int ia[]={o, 1,1,2,3,5,8,13,21};• 那么只简单写 ia;• 意味着什么呢?在这个例子中 ia的类型是 int*,因此下
面两种形式: ia;• &ia[0]; 是等价的,它们都返回数组第一
个元素的地址。
44 .. 22 .. 4 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;
在在 CC 语言中是利用库函数语言中是利用库函数 mallocmalloc 和和 freefree 来分配和撤销内存来分配和撤销内存空间的。空间的。 C++C++提供了较简便而功能较强的运算符提供了较简便而功能较强的运算符 newnew和和 deletedelete来取代来取代 mallocmalloc 和和 freefree函数。函数。注意: 注意: newnew和和 deletedelete 是运算符,不是函数,因此执行效率是运算符,不是函数,因此执行效率高高 ..newnew 运算符的例子: 运算符的例子: new int; new int; new int(100); new int(100); new char[10];new char[10];float *p=new float(3.14159);float *p=new float(3.14159);返回首地址返回首地址 ,, 用户可以根据该指针的值用户可以根据该指针的值 (( 是否为空是否为空 ))判断分判断分
配空间是否成功配空间是否成功
4.3 4.3 动态内存分配动态内存分配
deletedelete运算符使用的一般格式为运算符使用的一般格式为delete [ ] delete [ ] 指针变量指针变量例如要撤销上面用例如要撤销上面用 newnew 开辟的存放单精度数的空间开辟的存放单精度数的空间 (( 上面第上面第
55 个例子个例子 )) ,应该用,应该用delete pdelete p ;;前面用“前面用“ new char[10];”new char[10];”开辟的字符数组空间,如果把开辟的字符数组空间,如果把 nn
ewew 返回的指针赋给了指针变量返回的指针赋给了指针变量 ptpt ,则应该用以下形式的,则应该用以下形式的 deldeleteete运算符撤销该空间: 运算符撤销该空间: delete [] ptdelete [] pt ; ; //// 在指针变量前面加一对方括号,在指针变量前面加一对方括号,
表示是对数组空间的操作表示是对数组空间的操作
4.3 4.3 动态内存分配动态内存分配
小结 :• 理解数组的概念,掌握一、二维数组定义和使用方法• 会用数组存储和处理字符串,了解 String 类
思考题 : 编写程序将 n个数按逆序输出
作业题 : 用冒泡法对 10个字符按降序排序练习: 有如下结构: typedef struct {char m;string_no
de *next;}string_node 试利用这种结构存储字符串,并编制函数 search_max()
能够在这个字符串中检索出出现次数最多的字符。
Top Related