null第 5章 数组第 5章 数组null本章重点
一维数组
二维数组及多维数组
数组作为函数参数
字符数组与字符串5.1 数组的概念5.1 数组的概念一个班学生的学习成绩
一行文字
一个矩阵
这些数据的特点是:
1.数据量较大,数据不止一个
2.具有相同的数据类型
3.使用过程中需要保留原始数据 C++语言为这些数据,提供了一种构造数据类型:数组。所谓数组就是一组具有相同数据类型的数据的有序集合。 数组 数组 数组是由一定数目的同类元素顺序排列而成的结构类型数据;
一个数组在内存占有一片连续的存储区域;
数组名存储数组空间的首地址;
数组的每个元素用下标变量标识. 5.2 一维数组5.2 一维数组
一维数组是向量
一维数组的元素是基本类型(整型、字符型或者浮点型)、结构类型或类类型5.2.1 定义一维数组5.2.1 定义一维数组一般格式:
数据类型 数组名[ 常量
达式 ];整型、字符型和浮点型等符合标识符命名规则整型常量或常变量、符号常量。数组的长度例 int a[6] ;
char str[80];
const int M=30; //定义常变量M
float num[M];null例 int a[6]; 数组中有6个元素,占用一片连续的存储空间
每个元素的类型都是 int ,都占用4个字节
每个元素可以用数组名[下标]表示和访问,例如:a[2]
数组名代表数组中第一个元素的地址,也被称为数组首地址
a[2]地址为 a+2*45.2.2 引用一维数组中的元素5.2.2 引用一维数组中的元素 数组名 [ 表达式 ] 以下标方式访问数组 数组的地址整型表达式
地址偏移值例 int a[6];
访问第三个元素:a[2]5.2.2 引用一维数组中的元素5.2.2 引用一维数组中的元素例: int ary [ 10 ] , i = 3, j = 5 ; ary [ 0 ] = 1010ary [ i ] = 22ary [ j ] = ary [ i ]ary [ 2+j ] = 31312ary [ ary [ i ] ] = ary [ 0 ]10注意:
C++ 不提供对数组的
下标范围检查
ary[10]=10;//编译不报错
null5.2.3 一维数组的初始化与普通变量一样,可以在数组定义的同时,对数组元素赋初值例:int a1 [ 5 ] = { 1, 3, 5, 7, 9 };
int a2 [ 5 ] = { 0 } ;
int a3 [ 5 ] = { 1, 2, 3, } ;
int a4 [ ] = { 1, 2, 3, 4, 5, 6, 7 } ;
int a5 [ 5 ] = { 1, 2, 3, 4, 5, 6, 7 } ; // a3[3], a3[4]自动赋 0,后面的逗号可选// 自动定义数组长度为7 // 错误,初始化数据过多// 全部元素初始化为 0// 各元素分别赋初始值5.2.4 一维数组应用举例5.2.4 一维数组应用举例 访问数组中的所有元素例 int a[6];访问 a[0]
访问 a[1]
访问 a[2]
访问 a[3]
访问 a[4]
访问 a[5]访问 a[i] , i从0变化到5for ( i=0 ; i<6 ; i++)
访问 a[i];i作为循环控制变量以及下标访问:输出、运算、输入等操作null
#include
void main()
{ int a[ 5 ] = { 1, 3, 5, 7, 9 } ;
for ( int i = 0; i < 5; i ++ )
cout << a[ i ] << ends ;
cout << endl ;
static int b[ 5 ] = { 1, 2, 3 };
for ( i = 0 ; i < 5 ; i ++ )
cout << b[ i ] << ends ;
cout << endl ;
int c[ ] = { 1, 2, 3, 4, 5, 6, 7 } ;
for ( i = 0 ; i < sizeof ( c ) / sizeof ( int ) ; i ++ )
cout << c[ i ] << ends ;
cout << endl ;
}// 声明数组a并初始化 // 输出数组a的全部元素值 // 声明静态数组b并初始化 // 输出数组b的全部元素值 // 声明数组c,初始化,默认长度 7 // 输出数组c的全部元素值 int a[ 5 ] = { 1, 3, 5, 7, 9 } ;for ( int i = 0; i < 5; i ++ )
cout << a[ i ] << ends ;static int b[ 5 ] = { 1, 2, 3 };for ( i = 0 ; i < 5 ; i ++ )
cout << b[ i ] << ends ;int c[ ] = { 1, 2, 3, 4, 5, 6, 7 } ;for ( i = 0 ; i < sizeof ( c ) / sizeof ( int ) ; i ++ )
cout << c[ i ] << ends ;循环控制变量
作下标表达式// 例1 以下标方式访问数组例2:将一个整数插入到一有序的整数系列中恰当位置例2:将一个整数插入到一有序的整数系列中恰当位置:
10987null#include
void main( )
{
int a[11], t;
int i;
for ( i=0;i<10;i++)
{ a[i] = i*3; cout << a[i] << ends;}
cout<>t;
for( i=9;i>0;i--)
if ( t <= a[i] )
a[i+1]=a[i];
else
break;
a[++i]=t;
for( i=0;i<11;i++)
cout<0;i--)
if ( t < a[i] )
a[i+1]=a[i];
else
break; // 从后往前查找插入位置,并且移动数据 a[++i]=t;// 将t写入 // 输出数组中的元素 null例5.2 用数组求Fibonacci数列前20个数#include
#include
using namespace std;
int main()
{
int i;
int f[20]={1,1};
for(i=2;i<20;i++)
f[i]=f[i-2]+f[i-1];
for(i=0;i<20;i++)
{
if(i%5==0) cout<a[1],则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止——第一趟冒泡排序,结果最大的数被安置在最后一个元素位置上
(2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置
(3)重复上述过程,共经过n-1趟冒泡排序后,排序结束null—— 采用相邻元素比较的方法a[i]a[i+1]if (a[i] > a[i+1] ) 38499776139727975297例5.3 用起(冒)泡法对10个数按从小到大( 升序)排序第一趟起泡过程,7次比较for(i=1;i<8-1;i++)
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;}
}null—— 采用相邻元素比较的方法76137627例5.3 用起(冒)泡法对10个数按从小到大( 升序)排序第二趟起泡过程,6次比较7652a[i]a[i+1]if (a[i] > a[i+1] ) for(i=1;i<8-2;i++)
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;}
}null输出输入#include
using namespace std;
int main()
{
int a[10];
int i,j,t;
cout<<"input 10 numbers :"<>a[i];
cout<a[i+1])
{t=a[i];a[i]=a[i+1];a[i+1]=t;}
cout<<"the sorted numbers :"< a [ t ] )
t = j ;
if( t!=0 )
交换a[t]和a[0];第一趟选择排序null65(下标2)例 用选择排序法对10个数按从大到小( 降序)排序76 (下标4)7638 t = 1 ; //最大数所在的下标
for ( j = 2 ; j < = 4 ; j ++ )
if ( a[ j ] > a [ t ] )
t = j ;
if( t!=1 )
交换a[t]和a[1];第二趟选择排序null第一趟选择排序
t = 0 ; //最大数所在的下标保存在t ,初始值为0
for ( j = 1 ; j < = 4 ; j ++ )
if ( a[ j ] > a [ t ] )
t = j ;
if( t!=0 )
交换a[t]和a[0];第二趟选择排序
t = 1 ; //最大数所在的下标
for ( j = 2 ; j < = 4 ; j ++ )
if ( a[ j ] > a [ t ] )
t = j ;
if( t!=1 )
交换a[t]和a[1];……一共要做n-1次// n = 4for ( i=0 ; i a [ t ] )
t = j ;
if( t!=i )
交换a[t]和a[i];
}null#include
#include
#include
void main()
{
int a [10],i ;
srand ( time ( 0 ) ) ; //调用种子函数
for ( i = 0 ; i < 10 ; i ++ )
a[i] = rand() % 100 ; //用随机函数初始化数组
for ( i = 0 ; i < 10 ; i ++ )
cout << a[ i ] << ends ; //输出原始随机数序列
cout << endl ;
//接下来是排序种子函数。要求一个无符号整型参数置随机数生成器的启动值。为使种子值可变,用系统时间做srand函数的参数。
时间函数,在time.h定义,用0作参数时,返回系统当前时间 。随机函数。返回0~32767的随机值,该函数没有参数。例 用选择排序法对10个数按从大到小( 降序)排序nullrand()%100结果是随机数除以100后所得的余数,即限定随机的范围是在0~99之间; 使用rand()函数需添加头文件:#include 1. rand()函数
功能:是一个可以生成随机数的函数随机数函数返回的随机数在0~RAND_MAX(32767)之间;2. srand()函数
功能:用来设置随机数的种子,一般与rand()结合使用。否则直接用rand()的话,每次运行程序的产生的随机数都相同。补充知识:null选择排序//选择排序
int max , t ;
for ( i = 0 ; i < 10; i ++ )
{
t = i ;
for ( int j = i + 1 ; j < 10 ; j ++ ) //寻找最大元素
if ( a[j] > a[t] )
t = j ;
if ( t != i )
{
max = a[i] ; //交换数组元素
a[i] = a[t] ;
a[t] = max ;
}
}
//输出排序的结果
for ( i = 0 ; i < 10 ; i ++ )
cout << a[ i ] << " " ;
cout << endl ;
}例 用选择排序法对10个数按从大到小( 降序)排序交换a[t]和a[i]5.3 二维数组的定义和引用5.3 二维数组的定义和引用具有两个下标的数组称为二维数组
二维数组可以看成是一个表格
二维数组中的每一个元素是类型相同、长度相等的一维数组一维数组5.3.1 定义二维数组5.3.1 定义二维数组一般格式:
数据类型 数组名[ 常量表达式1 ] [ 常量表达式 2] ;整型、字符型和浮点型等符合标识符命名规则整型常量或常变量、符号常量。数组的长度例 int a[ 3 ][ 4 ]; // 二维数组,3 行4列3 4 =12个元素
float b[ 2 ][ 5 ]; // 二维数组,2行5列
int c[ 2 ][ 3 ][ 4 ]; // 多维数组,2 3 4 =24 个元素
int d[3,4]; ()null二维数组存储理解例 int a[3][4];
每行元素a[i]由包含4个元素
的一维数组组成二维数组a是由3行元素组成存储空间内是一个一维数组5.3.2 二维数组元素的引用5.3.2 二维数组元素的引用 数组名 [ 表达式1 ] [ 表达式2 ]
以下标方式访问数组 例 int a[ 3 ][ 4 ];
访问2行1列的元素:a[ 2] [ 1 ]
约定:行列值从0算起null5.3.3 一维数组的初始化与一维数组一样,可以在数组定义的同时,对二维数组中的元素赋初值例:
int i [ 2 ] [ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 } } ; // 数组初始化
int j [ 2 ] [ 3 ] = { 1, 2, 3, 4, 5, 6 } ; // 与 i 数组初始化方式等价
int a [ ] [ 4 ] = { 1, 2, 3, 4, 5, 6,7, 8 } ; //缺省第一维长度
int k [ ] [ 2 ] [ 3 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } ;
// 缺省第一维长度
int p [ ] [ 4 ] = { { 1 }, { 1 }, { 1 } } ;
// 仅对第 0 列元素赋初 值{1,0,0,1,0,0,1,0,0}
int m [ 3 ] [ ] = { 1, 2, 3, 4, 5, 6 } // 错误,不能省略第二维长度null访问二维数组中元素的方法
设有数组 a[m][n];
1.访问某行上的所有元素:
例如:a[0][0], a[0][1], a[0][2]…… a[0][n-1] 或
for(j=0; j<=n-1; j++) 访问a[0][j]
2.访问某列上的所有元素:
例如 : a[0][0], a[1][0], a[2][0]…… a[n-1][0]
for(j=0; j<=m-1; j++) 访问a[j][0]for( i=0 ; i
#include
#include
#include
void main()
{
int a[5][5];
int i,j;
//调用种子函数
srand ( time ( 0 ) ) ;
//用随机函数初始化数组
for ( i = 0 ; i < 5 ; i++)
for ( j = 0; j < 5 ; j++)
a [ i ][ j ] = rand() % 100 ; 例 为二维数组中所有元素提供值并输出//输出原始随机矩阵
for ( i = 0 ; i < 5 ; i++)
{
for ( j = 0; j < 5 ; j++)
cout << setw(5)<< a[i][j] ;
cout << endl ;
}
}5.3.4 二维数组应用举例5.3.4 二维数组应用举例例5.4 将二维数组行列元素互换,存到另一个数组中#include
using namespace std;
int main()
{
int a[2][3]={{1,2,3},{4,5,6}};
int b[3][2],i,j;
cout<<"array a:"<
using namespace std;
int main()
{ int i,j,r=0,c=0,m;
int a[3][4]={{5,12,23,56},{19,28,37,46},{-12,-34,6,8}};
m=a[0][0];
for ( i=0 ; i<=2 ; i++ )
for ( j=0; j<=3; j++ )
if ( a[ i ][ j ] > m )
{ m = a[ i ][ j ];
r = i; //保存最大数所在的行
c = j; //保存最大数所在的列
}
cout<<"max="<<"a["<
using namespace std;
int add(int x, int y)
{
x=2*x;
y=2*y;
return x+y;
}
int main( )
{ int a[2]={3,4};
int sum;
sum = add( a[0] , a[1] );
cout<
using namespace std;
int main( )
{void select(int b[],int n); //函数声明
int a[10],i;
cout<<"enter the original array:"<>a[i];
cout<内容不予处理。形参一维数组的声明中可以写元素个数,也可以不写。
函数首部的下面几种写法都合法,作用相同。
void select(int b[10],int n) //指定元素个数与实参数组相同
void select (int b[],int n) //不指定元素个数
void select (int b[5],int n) //指定元素个数与实参数组不同
C++实际上只把形参数组名作为一个指针变量来处理,用来接收从实参传过来的地址。例:形参一维数组的大小可不指定例:形参一维数组的大小可不指定#include
using namespace std;
float average1 ( float array[4] ) //求平均值
{
int i;
float aver,sum=array[0];
for(i=1;i<4;i++)
sum=sum+array[i];
aver=sum/4;
return aver;
}
float average2 ( float array[ ] , int n )
{
int i;
float aver,sum=array[0];
for(i=1;i>score[i];
aver= average1 (score) ;
cout<<"average1 score is "<
using namespace std;
int main( )
{int max(int array[ ][4] ); //函数原型
int a[3][4]={{11,32,45,67},{22,44,66,88},{15,72,43,37}};
cout<<"max value is"<< max( a ) <m) m=array[i][j];
return m;
}例:求矩阵中所有元素中的最大值null 在第二维大小相同的前提下,形参数组的第一维可以与实参数组不同。例如:
实参数组定义为
int score[ 5 ][ 10 ];
形参数组可以声明为:
int array[ 3 ][ 10 ]; //列数与实参数组相同,行数不同
int array[ 8 ][ 10 ];
实参数组名score代表其首元素(即第一行)的起始地址,系统不检查第一维的大小。
如果是三维或更多维的数组,系统不检查第一维的大小,其它维的大小都要检查。小结与强调:小结与强调: 数组元素作为函数参数——值传递
数组名作为函数参数 ——传地址
传地址与传值的区别:
传值:
实参将值传给形参后,之后两者没有关系
形式参数将另外分配存储空间,在函数调用结束后释放
传地址:
实参将地址传给形式参数,形参、实参指的是同一个存储空间
形式参数并不另外分配存储空间,在函数调用结束后,在函数中对形式参数所做的改变可以反映到实际参数上,不会随着形式参数的释放而消失5.4 用数组名作函数参数5.5 字符数组5.5 字符数组存放字符数据的数组5.5.1 字符数组的定义和初始化一般形式:
char 数组名[常量表达式];例如:
char c[4]; /*每个元素占一个字节 */
char str[2][5];null 字符数组的初始化方式1.逐个字符对数组元素赋初始值:
例如:
char str1[10] = { 'S', 't', 'u', 'd', 'e', 'n', 't' } ;普通数组
不添加 '\0' 2.用串常量初始化字符数组char str2[10] = { "Student" } ;
char str3[] = { "Student" } ;
char str4[] = "Student" ; 字符串添加 ‘\0’作为串尾结束标记 5.5.2 字符数组的赋值与引用5.5.2 字符数组的赋值与引用只能对字符数组的元素赋值,不能用赋值语句对整个数组进行赋值例如:
char a[5];
c={‘C’,’h’,’i’,’n’,’a’}; //错误,不能对整个数组一次赋值
c[0]=‘C’; c[1]=‘h’; c[2]=‘i’; c[3]=‘n’; c[4]=‘a’;
//正确,可以逐个元素赋值不能对整个数组整体赋值例如:
a=b; //错误null5.5.3 字符串和字符串结束标志C++语言将字符串作为字符数组来处理。
字符串常量:“CHINA”,在机内被处理成一个无名的字符型一维数组。C++语言中约定用‘\0’作为字符串的结束标志,它占内存空间,但不计入串长度。有了结束标志‘\0’后,程序往往依据它判断字符串是否结束,而不是根据定义时设定的长度。null字符串与字符数组的区别:char a[ ]={‘C’,’H’,’I’,’N’,’A’};char c[ ]=“CHINA”; 字符数组字符串串尾结束标记null可以用字符串的形式为字符数组赋初值char c[ ]={“I am a boy”}; /*长度11字节,以‘\0’结尾 */char a[ ]={‘I’, ‘ ’, ‘a’, ‘m’, ‘ ’, ‘a’, ‘ ’ , ‘b’, ‘o’, ‘y’};
/* 长度10字节 */如果数组定义的长度大于字符串的长度,后面均为‘\0’。char c[10]=“CHINA”; ‘\0’的ASCII为0,而‘ ’(空格)的ASCII为32。nullchar w[ ]={‘T’, ‘u’, ‘r’, ‘b’, ‘o’, ‘\0’};char w[ ]={“Turbo\0”};char w[ ]=“Turbo\0”;char w[ ]=‘Turbo\0’;非法nullchar a[2][5]={“abcd”, “ABCD”};str为字符数组在内存中存储的地址,一经定义,便成为常量,不可再赋值。char str[12]=“The String”;非法,在语句中赋值定义数组,开辟空间时赋初值null利用字符串结束标记处理字符数组char c[10]=“CHINA”; 例:对字符串进行加密,#include
int main()
{ char c[10]="CHINA"; //将字符串存放于数组
int i;
while(c[i]!='\0') //加密
{ c[i]=c[i]+4;
i++;
}
for(i=0;i<=10;i++) //输出字符串
if(c[i]!='\0')
cout<>str[i]; //A
......
A行将输入的十个字符依次送给数组str中的各个元素。定义赋值5.5.4 字符数组的输入和输出null把字符数组作为字符串批量输入输出。
对于一维字符数组的输入,在cin中仅需给出数组名;
输出时,在cout中也只给出数组名。void main (void )
{char s1[50],s2[60];
cout << “输入二个字符串:”;
cin >> s1;
cin >> s2;
cout << “\n s1 = “ << s1;
cout << “\n s2 = “ << s2 << “\n”;
}输入:abcd
stringcin的输入遇到空格或回车结束,并在串尾加结束标记数组名数组名输出到‘\0’为止null//例 字符数组的访问
#include
void main()
{ char ca [5] = { 'a' , 'b' , 'c' , 'd' , 'e' } ;
for ( int i = 0 ; i < 5 ; i ++ )
cout << ca [i] ; //逐个数组元素输出
cout << endl ;
cout << ca << endl ; //整体输出字符数组
}数组初始化
没有结束符, 普通字符数组5.5.4 字符数组的输入和输出可以正确显示字符串找不到结束符
字符串后显示无意义符号null//例 字符数组的访问
#include
void main()
{ char ca [5] = { 'a' , 'b' , 'c' , 'd' , 'e' ,’\0’} ;
for ( int i = 0 ; i < sizeof( ca) ; i ++ )
cout << ca [i] ; //逐个数组元素输出
cout << endl ;
cout << ca << endl ; //整体输出字符数组
}计算字节数
Sizeof 操作符查看对象在内存中所占的单元字节
可以正确显示字符串5.5.4 字符数组的输入和输出添加结束符,称为存放字符串的数组null//例 字符数组的访问
#include
void main()
{char cd[ ] = "I am a student." ;
for ( int i = 0 ; cd[i] != '\0' ; i ++ )
cout << cd[i] ;
cout << endl ;
cout << cd << endl ;
}自动添加结束符5.5.4 字符数组的输入和输出null//例 字符数组的访问
#include
void main(){
char ce[10] ;
cin >> ce ; //输入数组元素
cout << ce << endl ; //整体输出字符数组
}接受输入
遇空格或换行结束5.5.4 字符数组的输入和输出null//例 字符数组的访问
#include
void main(){ char ce[10] ;
cin >> ce ;
cout << ce << endl ;
}思考:要从键盘上接收空格字符怎么办?5.5.4 字符数组的输入和输出null字符串的输入
读取一个字符:cin.get()
例如: letter=cin.get()
也可以用来输入一串字符到数组
例如: char str[80]; cin.get(str,80);
与cin>>str的区别在于允许输入空格
读取一行字符到数组
格式: cin.getline(数组名,数组所含字符个数,结束标记)
例如: char str[50]; cin.getline(str,80,’\n’);
也可以输入空格null当要把输入的一行作为一个字符串送到字符数组中时,则要使用函数cin.getline( )。这个函数的第一个参数为字符数组名,第二个参数为允许输入的最大字符个数。 cin.getline(数组名, 数组空间数);char s1[80];
.......
cin.getline(s1, 80);首先开辟空间参数是数组名nullvoid main (void )
{ char s3[81];
cout<<”输入一行字符串:”;
cin.getline(s3,80); //A
cout<<”s3=”<='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')&&word==0)
{ word=1;
num++;
}
else if(s[i]==' '||s[i]=='\t')
word=0;
i++;
}
cout<<"num="<所有字符串处理函数的实参都是字符数组名或者: #include
using namespace std;null(1)合并两个字符串的函数 strcat (str1, str2)static char str1[20]={“I am a ”};
static char str2[ ]={“boy”};
strcat (str1, str2);将第二个字符串 str2 接到第一个字符串 str1 后。注意:第一个字符串要有足够的空间。空间足够大null(2) 复制两个字符串的函数 strcpy (str1, str2)static char str1[20]={“I am a ”};
static char str2[ ]={“boy”};
strcpy (str1, str2);strcpy ( str1, “CHINA”);strcpy (“CHINA”, str1);str1=str2; str1=“CHINA”; 字符串正确赋值均为非法null(3) 比较两个字符串的函数 strcmp (str1, str2)此函数用来比较str1和str2中字符串的内容。函数对字符串中的ASCII字符逐个两两比较,直到遇到不同字符或‘\0’为止。函数值由两个对应字符相减而得。该函数具有返回值,返回值是1 或 0 或 -1
str1 > str2 返回值是1
str1 == str2 返回值是0
str1 < str2 返回值是-1 if ( strcmp (str1, str2) ==0 )
{ ........ }用来判断两字符串是否相等nullstatic char str1[20]={“CHINA”};
static char str2[ ]={“CHINB”};
cout<< strcmp (str1, str2)<