第五章 数组

声明

本文内容大多取自《高级语言程序设计一书》,为本人学习笔记记录,切勿用于商业用途。

在这里插入图片描述

数组的定义数组是具有相同数据类型的一组有序数据的集合

数组中的数据称为数组元素,数组元素通过数组名和下标引用,下标是数组 元素在数组中的位置序号,表示该数组元素在数组中的相对位置。

第一节 一维数组

一、一维数组的定义

数组中的数据称为数组元素,数组元素通过数组名和下标引用,下标是数组 元素在数组中的位置序号,表示该数组元素在数组中的相对位置。

数组同变量一样,必须先定义后使用。数组占用内存单元,在定义数组时必须指定数组元素的 数据类型和数组元素的个数,这样才能为其分配相应的内存单元。
一维数组是只有一个下标的数组,其定义的一般形式:

数据类型符 数组名 1[长度 1],数组名 2[长度 2],;

其中:
1)“数据类型符”是指数组元素的数据类型。数据类型可以是任何基本类型。
2)“数组名”与变量名一样,必须遵循标识符的命名规则。
3)“长度”必须是整型的常量表达式,必须用一对方括号括起来,表示数组的元素个数(又称 数组长度),可由整型常量或符号常量组成,但其中不能出现变量。
需要注意的是,在数组定义时“长度”外面的一对方括号,以及数组元素引用时 “下标表达式”外面的一对方括号,都是C语言语法规则要求的。

4、数组元素的下标是元素相对于数组首地址或起始地址的偏移量,所以从0开始 顺序编号。
5、数组名表示整个数组所占用的内存空间的首地址。同一数组中的所有元素, 按其下标的顺序占用若干连续的存储单元。
6、一个数组定义语句中可以只定义一个数组,也可以定义多个数组,还可以同 时定义数组和变量。
【例 1】一维数组定义的例子。

int a[10],w; /*定义一个长度是 10 的整型数组 a 和一个整型变量 w*/
float b[20],x; /*定义一个长度是 20 的单精度实型数组 b 和一个单精度实型变量 x*/ 
double c[30],y; /*定义一个长度是 30 的双精度实型数组 c 和一个双精度实型变量 y*/ 
char d[40],z; /*定义一个长度是 40 的字符型数组 d 和一个字符型变量 z*/

在这里插入图片描述

二、一维数组元素的引用

引用一维数组中任意一个元素的方法:

数组名[下标]

其中:
1)“下标”可以是一个整型常量、整型变量或整型表达式,其取值范围是 0~(长度-1)。需 要注意的是,在 C 程序运行过程中,系统并不自动检查数组元素的下标是否越界,即下标可以不在 0~(长度-1)的合法范围内。
2)任何一个数组元素,本质上就是一个变量,它具有和相同类型单个变量一样的属性,可以被 赋值,可以接收键盘输入的数据,也可以组成表达式。如果数组元素参与表达式运算,则必须已被 赋值。
3)C 语言中,数组作为一个整体,不能参与数据运算,只能对单个的数组元素进行处理。
4)定义一维数组后,则需要为其所有的元素分配内存单元,一维数组占用的内存字节数=数组 长度×每一元素占用的字节数,而且所占用的内存单元是连续的,并按照元素顺序依次排列。

【例】

#include <stdio.h> 
void main() 
{ 
	int i,a[10];
	for(i=0;i<=9;i++)
		a[i]=i;
	for(i=9;i>=0;i--)
		printf("%d\n",a[i]); 
}

运行结果:在这里插入图片描述

三、一维数组的初始化

数组元素和变量一样,可以在定义时对数组元素赋初值,称为数组的初始化。
一维数组初始化的一般格式:

数据类型符 数组名[长度]={初值表},;

具体地,一维数组的初始化可以分为以下几种情况:
1、给一维数组的全部元素赋初值。
例如:设int a[4]={1,2,3,4};

2、给一维数组的部分元素赋初值。
设int a[4]={1,2};
3、初值的个数不能超过一维数组元素的个数。
例如:int a[4]={1,2,3,4,5};
一维数组a的长度是4,而初值的个数是5,初值的个数超出了数组长度,则编译 时系统会报错。
4、给一维数组的全部元素赋初值时允许省略数组长度的说明。
例如:

int a[4]={1,2,3,4}; 则可以写成:int a[]={1,2,3,4};

需要注意的是,只能给数组元素赋值,不能给数组名赋值,因为数组名代表数组 的首地址,数组名是常量。
在这里插入图片描述
【例】 用数组来处理求Fibonacci数列问题

#include <stdio.h> 
void 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) printf("\n");
		printf("%12d",f[i]);
	} 
	printf("\n");
}

在这里插入图片描述
【例2】将 5 个整数保存到一维数组后输出。

#include <stdio.h>
int main()
{
	int i,a[5]={1,2,3,4,5};
	//下标从0开始,0,1,2,3,4
	for(i=4;i>=0;i--)
	{	
		
		printf("%d\n",a[i]);
	}

}

在这里插入图片描述
【例3】从键盘输入数据为数组各元素赋值。

#include <stdio.h>
int main()
{
	int i,a[5];
	for(i=0;i<=4;i++)
	{
		scanf("%d",&a[i]);
	}
		
	for(i=4;i>=0;i--)
	{
		printf("%d\n",a[i]);

	}
	

}

运行结果:
在这里插入图片描述

第二节 二维数组

二维数组的定义:

二维数组也需要先定义后使用,二维数组的定义形式:

数据类型符 数组名[行长度][列长度],;

1、数据类型可以是任何基本类型。
2、数组名和变量名一样,必须遵循标识符的命名规则。
3、行长度说明二维数组有几行,列长度说明二维数组有几列。行长度和列长度 都是一个“整型常量表达式”,表达式中不能出现变量。
4、二维数组的元素个数=行长度*列长度。
5、二维数组元素在内存中的排列顺序是“按行存放”,即先顺序存放第一行的 各个元素,再存放第二行的各个元素,依此类推。
6、可以把二维数组看作是一种特殊的一维数组,其每个元素都是一个一维数组。
7、一个数组定义语句中可以只定义一个二维数组,也可以定义多个二维数组;可 以在一条定义语句中同时定义一维和二维数组,同时还可以定义变量。
在这里插入图片描述

二维数组的初始化

二维数组的初始化分为以下几种情况。
1、按行给二维数组的全部元素赋初值,其一般形式:

数据类型符 数组名[行长度][列长度]={{0行初值表},{1行初值表},,{最后一行 初值表}};

2、按二维数组在内存中的排列顺序给各元素赋初值,即不分行给二维数组的全 部元素赋初值,其一般形式:

数据类型符 数组名[行长度][列长度]={初值表};

3、只对每行的前若干个元素赋初值,此时所有未赋初值的二维数组二维数组元 素均为0值(即对于整型二维数组是0,对于实型二维数组是0.0,对于字符型二 维数组是‘\0’)。
4、只对前若干行的前若干个元素赋初值,此时所有未赋初值的的数组元素均为0 值。
5、如果对全部元素都赋初值,则“行长度”可以省略。需要注意的是只能省略 “行长度”,但第二维的长度即“列长度”不能省略。使用这种方式赋初值,允 许给出的初值不是列长度的整数倍。此时,行长度=初值个数整除列长度后加1。
6、如果分行给所有行的前若干个元素赋初值,则行长度可以省略。
在这里插入图片描述
【例】
将二维数组行列元素互换,存到另一个数组中。
在这里插入图片描述

#include <stdio.h> 
void main() 
{ 
	int a[2][3]={{1,2,3},{4,5,6}}; 
	int b[3][2],i,j;
	printf("array b:\n"); 
	for(i=0;i<=1;i++) 
	{
		for(j=0;j<=2;j++)
		{ 
			printf("%5d",a[i][j]); 
			b[j][i]=a[i][j];
	} 
		printf("\n"); 
	}
	printf("array a:\n");
	for(i=0;i<=2;i++)
	{ 
		for(j=0;j<=1;j++) 
			printf("%5d",b[i][j]); 
		printf("\n");}
}

在这里插入图片描述

第三节 字符数组和字符串

一、字符数组

字符数组的定义和初始化
一维字符数组,用于存储和处理一个字符串,其定义格式与一维数值型数组一样。 一维字符数组的定义形式:

char 数组名[数组长度]={初值表};

其功能是定义一维字符型数组,并为其赋初值。
【例】

char c[10], ch[3][4];

在这里插入图片描述
一维字符数组的初始化

1、一维字符数组的初始化
(1)用字符初始化字符数组
例如:

char str1[8]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,‘\0};
char str2[5]={‘C’,‘h’,‘i’,‘n’,‘a’};

(2)用字符串初始化字符数组
例如:

char str1[8]={“program”}

字符串是用双引号括起来的一串字符。在字符串末尾系统会自动地添加一个字符 串结束标志符‘\0’,表示字符串在此位置结束。字符‘\0’的ASCⅡ码值为0, 称为空字符,它不作为字符串的有效标志,只起到标志结束的作用,但需要占用1 字节的内存空间。
(3)用字符的ASCⅡ码值初始化字符数组。
例如:

char str1[8]={112,114,111,103,114,97,109,0};

(4)初始化时如果只提供了部分元素的值。未提供初值的元素自动赋值为‘\0’。
例如:

char str1[10]={“program”}

二维字符数组的初始 化
(1)用字符初始化二维字符数组。
例如:

char s[2][10] ={
{ ‘c’,‘o’,‘m’,‘p’,‘u’,‘t’,‘e’,‘r’}, 
{‘s’,‘c’,‘i’,‘e’,‘n’,‘c’,‘e’}
};

(2)用字符串初始化二维字符数组。
例如:

char s[2][10]={“computer”,“science”};

二维字符数组在初始化时,未提供初值的元素自动赋值为‘\0’。
在这里插入图片描述

字符数组的输入和输 出

1、一维字符数组的输入和输出
(1)使用scanf()和printf()函数
逐个字符输入和输出。在scanf()函数或printf()函数中用“%c”格式说明符每 次输入或输出一个字符,重复该过程完成整个字符串的输入和输出。

将字符串整个输入和输出。在scanf()函数或printf()函数中用“%s”格式说明 符一次性输入或输出整个字符串。
(2)使用gets()和puts()函数。使用字符串输入函数gets()或字符串输出函数 puts()将字符串整个输入或输出。
在这里插入图片描述

3、二维字符数组的输入和输出
(1)二维字符数组的输入。
对于二维字符数组,除了可以使用初始化的方法赋值外,还可以从键盘赋值。 二维字符数组的每一行可以看作一个一维字符数组,可以将二维字符数组的每 一行作为一个一维字符数组进行输入和输出。

二、字符串

字符串的定义和初始化:
字符串是指若干有效字符的序列,可以包括字母、数字、专用字符和转义字符等。
赋值方法有:

# 第一种方式是按单个字符的方式赋初值,其必须有一个是字符串的结束标志 符‘\0’; 
# 第二种方式是直接在初值表中给出一个字符串常量。

需要注意的是,由于系统在存储字符串常量时,会在字符串末尾自动加 上一个结束标志符‘\0’,所以无需认为添加。另外,由于字符串结束标志符 ‘\0’也需要在字符数组中占用一个元素的存储空间,即1字节,因此在说明 字符数组长度时,至少为字符串所需长度加1。

字符串的输入和输出
1、使用函数scanf( )和printf( )
(1)逐个字符的输入和输出。在scanf()或printf()函数中使用“%c”格式说 明符每次输入或输出一个字符,重复执行多次完成整个字符串的输入或输出。
(2)字符串的整体输入和输出。在scanf()或printf()函数中使用“%s”格式 说明符一次性输入或输出整个字符串。
(3)使用“%s”格式说明符输入字符串时,遇到空格或回车则认为字符串输 入结束。
(4)使用“%s”格式说明符输出字符串时,一旦遇到‘\0’则结束输出 (‘\0’不输出),其后字符不在输出。
2、使用函数gets( )和puts( )

使用字符串输出函数gets()或字符串输入函数puts()将字符串整体输入或输出。
1、字符串输入函数gets( )
【调用格式】gets(字符数组名)
【参数】字符数组名是已经定义的字符数组名。
【功能】从标准输入设备即键盘上输入一个字符串(可以包含空格,仅以回车 作为结束标志),并将其存储到指定的字符数组中。
【返回值】字符数组的首地址。

【说明】
1、gets( )函数输入的字符串的长度没有限制,编程者应保证字符数组有足够 大的空间,存放输入的字符串。
2、gets( )函数和使用“%s”格式说明符的scanf()函数都可以从键盘输入字 符串,但两者是有区别的。对于scanf()函数,回车和空格符都看成是输入字 符串的结束标志;对于gets()函数输入字符串中允许包含空格,只有回车才看 作是输入字符串的结束标志。

在这里插入图片描述
2、字符串输出函数puts( )

【调用格式】puts( )
【参数】字符数组名是已经存放字符串的字符数组名。
【功能】把字符数组名中所存放的字符串,输出到标准输出设备即显示器,并 以‘\n’取代字符串的结束标志‘\0’。所以用puts()函数输出字符串时,不 要求另外加换行符。
【返回值】无。
【说明】
1、字符串中允许包含转义字符,输出时产生一个控制操作。
2、puts()函数和使用“%s”格式说明符的printf()函数都可以输出字符串,但 两者是有区别的。对于printf()函数,不输出字符串结束标志符;对于puts()函 数,字符串结束标志符‘\0’转换为‘\n’输出。此外,puts()函数一次只能 输出一个字符串,而printf()函数用来输出字符串时一次可以输出多个。

在这里插入图片描述
3、字符串比较函数strcmp( )
【调用格式】strcmp(字符串1,字符串2)
【参数】“字符串1”和“字符串2”可以是字符串常量,也可以是已经存放 字符串的字符数组名。
【功能】比较两个字符串的大小,即两个字符串从左到右逐个字符进行比较 (按照ASCⅡ码值的大小进行比较),直到出现不同字符或遇到‘\0’为止。

如果“字符串1”等于“字符串2”,则函数返回值为0。
如果“字符串1”大于“字符串2”,则函数返回值是正整数(大于0的整数)。
如果“字符串1”小于“字符串2”,则函数返回值是负整数(小于0的整数)。

【说明】
1、如果一个字符串是另一个字符串从头开始的子串,则母串为大。
2、不能使用关系运算符“==”比较两个字符串,只能调用strcmp()函数进行 处理。

在这里插入图片描述
例:字符比较

//str这些开头的函数要有#include<string.h> 头文件支持 strcpy strpmp什么的
#include<stdio.h>
#include<string.h>
void main( )
{ 
	int i,j,k;
	char a1[ ]="wuhan", a2[ ]="beijing" ;
	i=strcmp(a1,a2);
	j=strcmp("china", "korea");
	k=strcmp(a2, "beijing" );
	printf("i=%d\nj=%d\nk=%d\n",i,j,k);
 }

在这里插入图片描述
3、字符串复制函数strcpy( )
【调用格式】strcpy(字符数组名,字符串[,整型表达式])
【参数】
“字符数组名”是已经定义的字符数组名。
“字符串”可以是字符串常量,也可以是已经存放字符串的字符数组 名
“整型表达式”可以是任何整型表达式,这一参数可以省略。

【功能】将“字符串”的前“整型表达式”个字符组成新的字符串复制到“字 符数组”中,若省略“整型表达式”,则将“字符串”完整地复制到“字符数 组中”,字符数组的原有内容被覆盖。

【返回值】字符数组的首地址
【说明】
1、字符数组长度必须足够大,以便容纳复制过来的字符串。复制时,连同字 符串结束标志‘\0’一起复制。
2、不能用赋值运算符“=”将一个字符串直接赋值给一个字符数组,只能调 用strcpy( )函数处理。
在这里插入图片描述
【例 】有3个字符串,要求找出其中最大者。
在这里插入图片描述

#include <stdio.h> 
#include <string.h> 
void main() 
{ 
	char string[20],str[3][20];
	int i; 
	for(i=0;i<3;i++) 
		gets(str[i]);     //for循环依次输入3组字符串
	if(strcmp(str[0],str[1])>0) //比较前两个字符串大小
		strcpy(string,str[0]); 
	else
		strcpy(string,str[1]); //把大的字符串赋值给srting
	if(strcmp(str[2],string)>0) //再拿大的字符串和第三个比较。,如果第三个大则把第三个的值赋值给string
		strcpy(string,str[2]); 
	printf("\nThe largest string is:\n%s\n",string); }

4、字符串连接函数strcat( )

【调用格式】

strcat(字符数组名,字符串)

【参数】
“字符数组名”是已经定义的存放字符串的字符数组名。 “字符串”可以是字符串常量,也可以是已经存放字符串的字符数组 名。
【功能】把“字符串”连接到“字符数组”中字符串的尾端(最后一个有效字 符的后面),组成新的字符串并存储到“字符数组”。“字符数组”中原来的 结束标志,被“字符串”的第一个字符覆盖,而“字符串”在操作中未被修改。
【返回值】字符数组的首地址。
【说明】
1、由于没有边界检查,编程者应注意保证字符数组长度足够大,以便容纳连 接后的新字符串;否则,会因长度不够出现问题。
2、连接前两个字符串都有结束标志‘\0’,连接后字符数组中存储的字符串 结束标志‘\0’被舍弃,只在新字符串的最后保留一个‘\0’。
【例】

#include<stdio.h>
#include<string.h>
void main()
{
	char str1[10]={"Hello!"};
	char str2[10]={"word!"};
	printf("%s\n",strcat(str1,str2));
}

输出:
在这里插入图片描述
5、测字符串长度函数strlen( )(其中len是length的缩写)
【调用格式】strlen(字符串)
【参数】“字符串”可以是字符串常量,也可以是已经存放字符串的字符数组 名。
【功能】测字符串(字符串常量或字符数组)的实际长度(不包含字符串结束 标志符‘\0’)。
【返回值】字符串的实际长度。

【例】:测试字符串长度

#include<stdio.h>
#include<string.h>
void main()
{
	char a1[10]=" china" ;
	printf ("%d\n",strlen(a1));
	printf ("%d\n", strlen("beijing\0wuhan"));
}

运行结果:
PS:再次注意,使用“%s”格式说明符输出字符串时,一旦遇到‘\0’则结束输出 (‘\0’不输出),其后字符不在输出。
在这里插入图片描述
【例】 把输入的字符串逆序排列,并显示。

#include<stdio.h>
#include<string.h>
void main()
{
	char str[80];
	int temp,i,j;
	printf("Enter a string:\n"); 
	scanf("%s",str); 
	for(i=0,j=strlen(str)-1;i<j;i++,j--)
	{ 
		temp=str[i];
		str[i]=str[j]; /*交换i,j两个元素*/ 
		str[j]=temp;
	}
	printf("\nReversed string:\n%s\n",str);
}

在这里插入图片描述
6、字符串大写字母转换成小写函数strlwr( )
【调用格式】strlwr(字符串)
【参数】“字符串”可以是字符串常量,也可以是已经存放字符串的字符数组 名。
【功能】将字符串中的大写字母转换成小写字母,其他字符(包括小写字母和 非字母字符)不转换。
在这里插入图片描述

#include<stdio.h>
#include<string.h>
void main()
{
	char a1[6]="CHinA", a2[ ]="wuHAn" ; 
	printf ("%s\n",strlwr(a1)); 
	printf ("%s\n",strupr(a2));
}

在这里插入图片描述

posted @ 2022-11-21 21:20  那酒不要留  阅读(96)  评论(0编辑  收藏  举报
/* 雪花特效 */