数组是⼀组相同类型元素的集合;从这个概念中我们就可以发现:数组中存放的是1个或者多个数据,但是数组元素个数不能为0。数组中存放的多个数据,类型是相同的。 数组分为⼀维数组和多维数组,多维数组一般比较常见的是⼆维数组。
一般形式为
类型说明符 数组名[常量表达式]
存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的大小和数组的元素类型。
•数组中存放数据的类型,可以是: char、short、int、float 等,也可以 自定义的类型
• 数组名可根据实际情况,起的有意义就⾏。
• [ ] 中的常量值是⽤来指定数组的大小的,这个数组的大小是根据实际的需求指定就⾏。
举个例子:
现在想存储某个班级的30⼈的数学成绩,那我们就可以创建⼀个数组,如下:
int math[30];
我们也可以根据需要创建其他类型和大小的数组
char ch[15];
double score[20];
注意:
1.在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。例如,指定a[10],表示a数组有10个元素。注意,下标是从0开始的,这10个元素是a[0]。a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]。特别注意,按上面的定义,不存在数组元素a[10]。
2.常量表达式中可以包括常量和符号常量,如“int a[3+5];”是合法的。不能包含变量,如“int a[n];”是不合法的。也就是说,C语言不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。
3.用“int a[10];”定义了数组a后,在内存中划出一片存储空间,存放了一个有10个整型元素的数组(如果用VisualC++,此空间大小为4X10=40字节)。可以看到,用一个“int a[10];”,就相当于定义了10个简单的整型变量,显然简捷方便。
a数组
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
在定义数组并对其中各元素赋值后,就可以引用数组中的元素。注意:只能引用数组元素而不能一次整体调用整个数组全部元素的值。
引用数组元素的表示形式为
数组名[下标]
在C语⾔中数组的访问提供了⼀个操作符 [ ] ,这个操作符叫:下标引⽤操作符。 有了下标访问操作符,我们就可以轻松的访问到数组的元素了,⽐如我们访问下标为7的元素,我们就 可以使⽤ arr[7] ,想要访问下标是3的元素,就可以使⽤ arr[3]。
例如,a[0]就是数组a中序号为0的元素,它和一个简单变量的地位和作用相似。“下标”可以是整型常量或整型表达式。
例如下面的赋值表达式包含了对数组元素的引用:
a[0]=a[5]+a[7]-a[2* 3]
每一个数组元素都代表一个整数值。
注意:定义数组时用到的“数组名[常量表达式]”和引用数组元素时用的“数组名[下标]”形式相同,但含义不同。例如:
int a[10]; //前面有 int,这是定义数组,指定数组包含10个元素
t=a[6]; //这里的a[6]表示引用a数组中序号为6的元素
例题:对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求按逆序输出。
#include
int main()
{
int i,a[10];
for (i = 0; i < 10; i++)//对数组元素a[0]~a[10]赋值
a[i] = i;
for (i = 9; i >= 0; i--)//输出a[9]~a[0]共10个数组元素
printf("%d ", a[i]);
printf("\n");
return 0;
}
为了使程序简洁,常在定义数组的同时给各数组元素赋值,这称为数组的初始化。可以用“初始化列表"方法实现数组的初始化。
(1)在定义数组时对全部数组元素赋于初值。例如:
int a[10]={0,1,2,3,4.5,6.7,8,9);
将数组中各元素的初值顺序放在一对花括号内,数据间用逗号分隔。花括号内的数据就称为“初始化列表”。经过上面的定义和初始化之后
a[0]=0,a[1]=1,a[2]=2,a[3]=3 a[4]=4,a[5]=5,a[6]=6,a[7]=7,a[8]=8,a[9]=9。
(2)可以只给数组中的一部分元素赋值。
例如:
int a[10]={0,1,2,3,4};
定义a数组有10个元素,但花括号内只提供5个初值,这表示只给前面5个元素赋初值,系
统自动给后5个元素赋初值为0。
(3)如果想使一个数组中全部元素值为0,可以写成
int a[10]={0,0,0,0,0,0,0,0,0,0};或int a[10]={0}; //未赋值的部分元素自动设定为0
(4)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。例如:
int a[5]={1,2,3,4,5};可以写成int a[]={1,2,3,4,5};
在第2种写法中,花括号中有5个数,虽然没有在方括号中指定数组的长度,但是系统会根据花括号中数据的个数确定a数组有5个元素。但是,如果数组长度与提供初值的个数不相同,则方括号中的数组长度不能省略。例如,想定义数组长度为10,就不能省略数组长度的定义,而必须写成
int a[10]={1,2,3,4,5};
只初始化前5个元素,后5个元素为0。
说明:如果在定义数值型数组时,指定了数组的长度并对之初始化,凡未被“初始化列表”指定初始化的数组元素,系统会自动把它们初始化为0(如果是字符型数组,则初始化为'\0’,如果是指针型数组,则初始化为NULL,即空指针)。
sizeof 中C语⾔是⼀个关键字,是可以计算类型或者变量大小的, sizeof 也可以计算数组的
大小。
例如:
#include
int main()
{
int arr[10] = {0};
printf("%d\n", sizeof(arr));
return 0;
}
输出的结果为40,计算的是数组所占内存空间的总大小,单位是字节。
我们⼜知道数组中所有元素的类型都是相同的,那只要计算出⼀个元素所占字节的个数,数组的元素 个数就能算出来。这⾥我们选择第⼀个元素算大小就可以。
#include
int main()
{
int arr[10] = {0};
printf("%d\n", sizeof(arr[0]));//计算⼀个元素的⼤⼩,单位是字节
return 0;
}
接下来就能计算出数组的元素个数:
#include
int main()
{
int arr[10] = {0};
int sz = sizeof(arr)/sizeof(arr[0]);
printf("%d\n", sz);
return 0;
}
这⾥的结果是:10,表⽰数组有10个元素。 以后在代码中需要数组元素个数的地方就不⽤固定写死了,使⽤上⾯的计算,不管数组怎么变化,计 算出的大小也就随着变化了。
这个数列有如下特点:第1,2两个数为1,1。从第3个数开始,该数是其前面两个数之和。即该数列为1,1,2,3,5,8,13,.,用数学方式表示为
F=1 (n=1)
F2=1 (n=2)
F„=F+F2(n≥3)
这是一个有趣的古典数学问题:有一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少?
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int i;
int f[40] = { 1,1 };//对最前面两个元素f[0]和f[1]赋初值1
for (i = 2; i < 40; i++)
f[i] = f[i-2] + f[i-1];//以此计算f[2]到f[39]的值
for (i = 0; i < 40; i++)
{
if (i % 4== 0)
printf("\n");
printf("%12d", f[i]);
}
printf("\n");
return 0;
}
运行结果如下:
首先说一下冒泡法
冒泡排序的思想是每次将最大的一下一下运到最右边,然后将最右边这个确定下来。再来确定第二大的,再确定第三大的...
对于数组a[],具体的来说,每次确定操作就是从左往右扫描,如果a[i]>a[i+1],我们就将两项交换,然后再往右检查,这样可以找出最大的并将其丢到最右边。第一次确定操作是将a[1]~a[n]中最大的放到a[n];第二次确定操作是将a[1]~a[n-1]中最大的放到a[n-1]。
依此类推(类似地,如果你想先把最小的放到左边也是可以的)
由于排序过程中,数字像冒泡泡一样从左往右换过去,故名冒泡排序。
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int i, j, t,a[10];
printf("请输入10个整数:");
for (i = 0; i < 10; i++)
scanf("%d", &a[i]);
printf("\n");
for (j = 0; j < 9; j++)
for (i = 0; i < 9-j; i++)
if(a[i]>a[i+1])
{
t = a[i];
a[i] = a[i + 1];
a[i + 1] = t;
}
printf("排序之后数依次为:\n");
for (i = 0; i < 10; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
运行结果如下:
说明:当执行外循环第1次循环时,j=0,然后执行第1次内循环,此时i=0,在if语句中将 a[i]和 a[i+1]比较,就是将a[0]和 a[1]比较。执行第2次内循环时,i=1,a[i]和 a[i+1]比较,就是将a[1]和a[2]比较……执行最后一次内循环时,i=8,a[i]和 a[i+1]比较,就是将a[8]和 a[9]比较。这时第1趟过程完成了。
当执行第2次外循环时,j=1,开始第2趟过程。内循环继续的条件是i<9一j,由于j=1,因此相当于i<8,即i由0变到7,要执行内循环8次...其余类推。
二维数组常称为矩阵。白二维数组写成行和列的排列形式,可以形象化地理解二维数组的逻辑结构。
二维数组其基本概念与方法和一维数组相似。如: float pay[3]6]; 以上定义了一个float型的二维数组,第1维有3个元素,第2维有6个元素。每维的度分别用一对方括号括起来。
二维数组定义的一般形式为
类型说明符 数组名[常量表达式][常量表达式];
例如:
float a[3][4],b[5][10];
定义a为3×4(3行4列)的数组,b为5X10(5行10列)的数组。
注意,不能写成
float a[3,4],b[5,10]; //在一对方括号内写两个下标,错误
注意:在内存中,各元素是连续存放的,不是二维的,是线性的。
拓展:定义三维数组,例如:
float a[2][3][4];//定义三维数组a,它有2页,3行,4列
二维数组元素的表示形式为
数组名[下标][下标]
例如,a[2][3]表示a数组中序号为2的行中序号为3的列的元素。下标应是整型表达式,如 a[2-1][2*2-1]。不要写成a[2,3]、a[2-1,2*2-1]形式。C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所⽰:
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
图中绿⾊的数字表示行号,第⼀⾏蓝⾊的数字表示列号,都是从0开始的,⽐如,我们说:第2 ⾏,第4列,快速就能定位出7。
在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。
不完全初始化
int arr1[3][5]={1,2};
int arr2[3][5]={0};
完全初始化
int arr4[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};
int arr4[3][5] = {{1,2},{3,4},{5,6}};
初始化时省略⾏,但是不能省略列
int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6,7};
int arr7[][5] = {{1,2},{3,4},{5,6}};
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a[3][3],sum=0;
int i, j;
printf("输入数据:\n");
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%3d", &a[i][j]);
for (i = 0; i < 3; i++)
sum = sum + a[i][i];
printf("%d", sum);
return 0;
}
运行结果如下:
#include
int main()
{
int i, j, row = 0, colum = 0, max;
int a[3][4] = { {1,2,3,4},{6,7,8,9},{10,-10,2,5} };//定义二维数组并赋初值
max = a[0][0];//先认为a[0][0]最大
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if (max < a[i][j])
{
max = a[i][j];
row = i;
colum = j;
}
printf("max=%d\nrow=%d\ncolum=%d\n", max, row, colum);
return 0;
}
运行结果如下: