目录
数组是具有相同的数据类型的有序数据的集合。
数组中的每一个元素都属于同一个数据类型。
用一个统一的数据名和下标来唯一地确定数组中的元素。
一、数组定义
1.1 数组的定义
- 数组名:变量集的共同名字。例,a
- 数组元素(Array Element):数组中的每一个成员变量。例,a[0]、a[1]、a[2]...
- 数据下标(Subscript):数组元素通过它在数组中的相对位置来引用。这个位置即下标值。下标总是从0开始。
- 数组大小(Array Size):数组所包含元素的个数。数组元素个数=下标最大值+1
1.2 数组的两个特征:
- 数组是有序的。数组元素之间按顺序排列,以小标(索引)确定它们之间的相对位置。
- 数组是同质的。同一数组中的每个元素是同类型。叫元素类型。
1.3 数组的分类:
按数组元素的数据类型可分为:
数值数组、字符数组、指针数组、结构数组等;
按数组中下标的个数可分为:
一维数组、二维数组、多维数组。
二、一维数组
2.1 定义
类型说明符 数组名 [常量表达式];
⬇️ ⬇️
指明数组元素的数据类型 下标:指明数组元素的总数,只能是常量。取值范围是[0,总数-1]
📝例如: int w [10]; 它表示数组名为w,此数组有10个元素。
- 符号常量指定数组大小。对于事先难以确定数组元素个数或为使元素个数具有通用性,可用符号常量指定数组大小。而符号常量应该根据实际应用中可能遇到的个数最大的数目确定。
例如: #define MAXELEMENTS 60
int p [MAXELEMENTS];
- 下标也可以是字符型数据。
例如: int b[‘A’]; 定义了一个有65个元素的自动整形数组b。
2.2 初始化
- 在定义语句中对数组元素赋值的方法称为数组的初始化。
- 数组初始化是在编译阶段完成的。
- C语言规定:数组的初始化只能对数组整体或部分数组元素赋值。
数组初始化的一般格式如下:
类型说明符 数组名 [数组长度]={各数组元素值};
🏷️①可以只给一部分元素赋值。
例如; int a [10] ={0,1,2,3,4};
定义a数组有10个元素,但华括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。
🏷️②如果想使一个数组中全部元素值为0,可以写成 int a [10] ={0};
不能写成 int a [10] ={0*10]; 即不能给数组整体赋初值。
🏷️③在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。
例如:int a [5] ={1,2,3,4,5}; 也可以写成 int a [ ] ={1,2,3,4,5};
2.3 引用
- 定义了数组后,就可以引用数组中的任意一个元素,引用形式如下: 数组名[下标表达式]
- 其中下标表达式可以是整常数或整形表达式,其取值范围从0开始,到元素个数-1为止。超出这个范围就称为数组下标越界。
📝 例:逐个输出10个学生的成绩,累加,再求平均值,输出比平均成绩高的学生成绩。
#include "stdio.h"
#define MAX 10
int main()
{
int a[MAX];
int i,j,t;
int sum=0;
float avg;
int num=0;
printf("请输入%d名学生的成绩:\n",MAX);
for(i=0;i<MAX;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
avg=sum/MAX;
for(i=0;i<MAX;i++)
printf("第%d名学生的成绩是:a[%d]=%d\n",i+1,i,a[i]);
printf("这个班的平均成绩是:%.2f\n",avg);
printf("高于平均成绩有:\n");
for(i=0;i<MAX;i++)
if(a[i]>avg)
{
num++;
printf("学号%d的学生的成绩是:%d\n",i+1,a[i]);
}
printf("共计高于平均成绩的人数有%d个。\n",num);
printf("将这个班的学生成绩按照升序依次输出:\n");
for(i=0;i<MAX-1;i++)
for(j=0;j<MAX-1-i;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
for(i=0;i<MAX;i++)
printf("%d\n",a[i]);
return 0;
}
三、二维数组
3.1 定义
二维数组定义的一般形式:
类型说明符 数组名 [常量表达式] [常量表达式] ;
📝例如:定义a为3×4(3行4列)的数组,b为5×10(5行10列)的数组。如下:
float a [3] [4] , b [5] [10] ;
🏷️注意: 我们可以把二维数组看作是一种特殊的一维数组:它的元素又是一个一维数组。
例如,可以把a看作是一个一维数组,它有3个元素:a[0]、a[1]、a[2],每个元素又是一个包含4个元素的一维数组。
3.2 引用
二维数组元素的表达形式为:
数组名 [下标] [下标]
例如:a [2] [3]
下标可以是整型表达式,如 a [2-1] [2*2-1]
🏷️在使用数组元素时,应该注意下标值应在已定义的数组大小的范围内。
定义a为3×4的数组,它可用的行下标值最大为2,列下标值最大为3。
3.3 初始化
数据类型 数组名 [常量表达式1] [常量表达式2]= {初始化数据};
🏷️①分行给二维数组赋初值。
如,int a [3] [4] ={{1,2,3,4,},{5,6,7,8},{9,10,11,12}};
这种赋初值方法比较直观,把第1个花括弧内的数据给第1行的元素,第2个花括弧内的数据赋给第2行的元素……即按行赋初值。
🏷️②可以将所有数据写在一个花括弧内,按数组排列的顺序对各元素赋初值。
如,int a [3] [4] ={1,2,3,4,5,6,7,8,9,10,11,12};
效果与前相同。但以第1种方法为好,一行对一行,界限清楚。 用第2种方法如果数据多,写成一大片,容易遗漏,也不易检查。
🏷️③可以对部分元素赋初值。如,int a [3] [4] ={{1},{5},{9}};
也可以对各行中的某一元素赋初值,如 Int a [3] [4] ={{1},{0,6},{0,0,0,11}};
也可以只对某几行元素赋初值。如,int a [3] [4] ={{1},{5,6}};
🏷️④如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。
如,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};
📝例:求平均成绩。
#include <stdio.h>
int main()
{
int a [5][3]={{98,95,99},{96,94,95},{99,93,99},{95,97,96},{99,98,97}};
int i,j;
float stusum=0,kemusum=0;
float stupj[5],kemupj[3];
for(i=0;i<=4;i++)
{
for(j=0;j<=2;j++)
{
stusum+=a[i][j];
}
stupj[i]=stusum/3;
printf("第%d个同学的平均成绩%.2f\n",i+1,stupj[i]);
stusum=0;
}
for(j=0;j<=2;j++)
{
for(i=0;i<=4;i++)
{
kemusum+=a[i][j];
}
kemupj[j]=kemusum/5;
printf("第%d科的平均成绩%.2f\n",j+1,kemupj[j]);
kemusum=0;
}
return 0;
}
四、字符数组
4.1 定义
用来存放字符数据的数组是字符数组。
字符数组中的一个元素存放一个字符。
4.2 初始化
对字符数组初始化,最容易理解的方式是逐个字符赋给数组中各元素。
如,char c [10]={'I',' ','a','m',' ','h','a','p','p','y'};
- 🏷️如果在定义字符数组时不进行初始化,则数组中各元素的值是不可预料的。
- 🏷️如果花括弧中提供的初值个数(即字符个数)大于数组长度,则按语法错误处理。
- 🏷️如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即'\0')。例如:
- 🏷️如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。例如:
📝例:钻石图案。
#include <stdio.h>
int main()
{
char diamond[5][5]={{'','','*','',''},{'','*','','*',''},{'*','','','','*'},{'','*','','*',''},{'','','*','',''}};
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
printf("%c",diamond[i][j]);
printf("\n");
}
return 0;
}
4.3 字符串
一般来讲,字符串是利用字符数组存放的。
其基本思想是:在每个字符数组的有效字符后面(或字符串末尾)加上一个特殊字符 '\0'(其ASCII码值为0),在处理字符数组的过程中,一旦遇到结束符 '\0',就表示已达到字符串末尾。
同时,C语言允许用一个简单的字符串常量初始化一个字符数组。
如:char c [ ]="Happy"; 等价于 char c [ ]={'H','a','p','p','y','\0'};
4.4 输入输出
字符数组的输入输出可以有两种方法:
- 逐个字符输入输出。用格式符 "%c"输入或输出一个字符。
- 将整个字符串一次输入或输出。用 "%s"格式符,意思是对字符串的输入输出。
说明:
- 前面介绍的输出字符串的方法:
- printf("%s",c);
- 实际上是这样执行的:按字符数组名c找到其数组起始地址,然后逐个输出其中的字符,直到遇 '\0' 为止。
- C语言用一维数组存放字符串,而且允许用数组名进行输入或输出一个字符串。
4.5 字符串处理函数
4.5.1 puts函数
其一般形式为:puts(字符数组)
🏷️其作用是将一个字符串(以 '\0' 结束的字符序列)输出到终端。假如已定义str是一个字符数组名,且该数组已被初始化为"China"。则执行puts(str); 其结果是在终端上输出China。
🏷️由于可以用printf函数输出字符串,因此puts函数用的不多
🏷️用puts函数输出的字符串可以包含转义字符。例如:
char str [ ]={"China\nBei jing"};
puts(str);
输出结果:China
Bei jing
4.5.2 gets函数
其一般形式为:gets(字符数组)
🏷️其作用是从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。
注意:用puts和gets函数只能输入或输出一个字符串,不能写成 puts(str1,str2) 或 gets(str1,str2)
4.5.3 strcat函数
其一般形式为:stecat(字符数组1,字符数组2)
🏷️其作用是连接两个字符数组中的字符串,吧字符串2接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值——字符数组1的地址。
4.5.4 strcpy函数
其一般形式为:strcpy(字符数组1,字符串2)
🏷️strcpy是“字符串复制函数”。
🏷️作用是,将字符串2复制到字符数组1中去。例如:
注意:
4.5.5 strcmp函数
其一般形式为:strcmp(字符串1,字符串2)
🏷️其作用是,比较字符串1和字符串2。
🏷️字符串比较的规则与其他语言中的规则相同,即对两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到 '\0' 为止。如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准。
比较的结果由函数值带回
(1)如果字符串1=字符串2,函数值为0。
(2)如果字符串1>字符串2,函数值为一正整数。
(3)如果字符串1
注意:
4.5.6 strlen函数
其一般形式为:strlen(字符数组)
🏷️strlen是测试字符串长度的函数。
🏷️函数的值为字符串中的实际长度(不包括 '\0' 在内)。
📝如: