目录
数组
数组的声明(使用数组前的准备)
访问数组(数组的使用方法)
数组的遍历
数组初始化
1.在声明变量时,除了必要的情况下,都需要对变量进行初始化。
2.我们还可以像下面在声明数组时不指定元素个数,数组会根据初始值的个数自动进行设置。
3.使用0对{}内没有赋初始值的元素进行初始化。
4.使用0对初始化数组内的全部元素
在初始化数组时,也有错误的操作
数组的复制
输入数组元素的值
对数组的元素进行倒序排列
使用数组进行成绩处理
对象式宏
数组元素的最大值和最小值
赋值表达式的判断
数组的元素个数
结语
学生的学籍号码、运动选手背后的号码、飞机高铁的座位号……在生活中我们经常遇到把具有相同性质的事物聚集在一起的情况,如果我们一个个列举就显得十分冗杂,不如统一使用号码来解决这个问题,比如输入成绩时,我们对学生进行编号,再按编号输入成绩,要是你在程序中输入一个一个学生的姓名呢?是不是很麻烦
接下来我们将为大家介绍为了提高相同效率而把具有相同类型的数据有序地组织起来的一种形式——数组。
数组
在没学数组之前让我们输入5个学生的成绩、总和及其平均分并显示出来,我们一定会声明5个变量通过printf与scanf函数进行输入输出,再次通过sum求和,进而求平均。
对于上述的处理,除了变量名不同外,执行的都是相同的操作,所以当数量超过一定数值时就不能再这样处理了。
擅长处理这类数据的就是数组,它通过号码把相同数据类型的变量集中起来进行管理。
注意
可以用数组实现相同类型的对象的集合。
统一类型的变量——元素集中起来,在内存上排成一条直线,这就是数组。
数组的声明(使用数组前的准备)
首先进行声明,数组的声明通过指定元素类型、变量名、元素个数来进行,并且[ ]中的元素个数必须是常量。
,,下面是声明数组a,是一个元素类型为int类型、元素个数为5的数组。
访问数组(数组的使用方法)
数组a的各个元素,都是int类型的对象,不允许一些元素是int类型一些元素是double类型。
对于数组内各个元素的访问(读取)都是自由的,访问元素使用的是“[ ]”称为下标运算符。[ ]中的操作数称为下标。
下标表示是首个元素之后的第几个元素,而不是数组中的第几个元素。
另外,数组声明中使用的[ ]仅仅是分隔符,而访问数组时使用的则是运算符。
a[b] 从数组a的首个元素起,访问b个元素后的元素 |
例如,从第一个元素开始访问是a[0],第二个元素是a[1]……第n个元素是a[n-1],不存在a[-1]、a[n]这样就溢出了。
数组的遍历
创建一个元素类型为int类型,包含5个元素的数组,依次把1—5赋值给它们并且进行显示。
#include<stdio.h>
int main()
{
int v[5];
v[0] = 1;//下标:0 1 2 3 4
v[1] = 2;//元素:1 2 3 4 5
v[2] = 3;
v[3] = 4;
v[4] = 5;
printf("v[0] = %d\n", v[0]);
printf("v[1] = %d\n", v[1]);
printf("v[2] = %d\n", v[2]);
printf("v[3] = %d\n", v[3]);
printf("v[4] = %d\n", v[4]);
return 0;
}
接下来我们使用for语句对其进行简化修改:创建变量i,是i从0递增到5,执行5次循环
#include<stdio.h>
int main()
{
int v[5];
int i;
for(i = 0; i < 5; i++)//为元素赋值
{
v[i] = i + 1;
}
for(i = 0; i < 5; i++)//显示元素的值
{
printf("v[%d] = %d\n", v[i], i);
}
return 0;
}
接下来我们来进一步显示它循环的过程:
i=1时,v[0]=0+1;
i=2时,v[1]=1+1;
………………
i=4时,v[4]=4+1;
像这样,按顺序逐个查看数组的元素,就称为遍历。
数组初始化
1.在声明变量时,除了必要的情况下,都需要对变量进行初始化。
int v[5] = {1, 2, 3, 4, 5};
最后一个初始值加不加逗号都可以。
2.我们还可以像下面在声明数组时不指定元素个数,数组会根据初始值的个数自动进行设置。
int v[] = {1, 2, 3, 4, 5};
3.使用0对{}内没有赋初始值的元素进行初始化。
int v[5] = {1, 2};//{1, 2, 0, 0, 0}
4.使用0对初始化数组内的全部元素
int v[0] = {0};//{0, 0, 0, 0, 0}
在初始化数组时,也有错误的操作
当初始值的个数超过超过数组的元素个数时,程序会发生错误。
int v[3] = {1, 2, 3, 4, 5};//初始化值过多
不能通过赋值语句进行初始化
int v[3];
v = {1, 2, 3};
数组的复制
我们把数组中的元素全部复制到另一个数组中。
#include<stdio.h>
int main()
{
int i;
int a[5] = {1, 2, 3};
int b[5];
for(i = 0; i < 5; i++)
{
b[i] = a[i] ;
}
puts(" a b");
puts(" -------");
for(i = 0; i < 5; i++)
{
printf("%4d%4d\n", a[i], b[i]);
}
return 0;
}
程序中的第一个for语句,作用是把a中的全部元素一次赋值给b中的元素
同时遍历两个数组,从b[0] = a[0]到b[4] = a[4]
C语言不支持基本赋值运算符,下面语句是错误的
b = a;//不能为数组赋值
注意
不能使用基本赋值运算符对数组进行赋值。数组的赋值必须通过使用循环语句对所有元素进行一一赋值。
第二个for语句时同时遍历两个数组,并且显示它们的值。
输入数组元素的值
从键盘中输入数组元素的值,并且一一显示它们。
#include<stdio.h>
int main()
{
int i;
int x[5];
for(i = 0; i < 5; i++)
{
printf("x[%d]:", i);//输入元素的值
scanf("%d", &x[i]);
}
puts("……………………");
for(i = 0; i < 5; i++)
{
printf("x[%d]=%d \n", i, x[i]);//显示元素的值
}
return 0;
}
对数组的元素进行倒序排列
如果仅仅是按照顺序对数组内的元素赋值没有什么难度,接下来我们对数组的元素进行倒序排列。
我们创建5个元素的int类型的数组进行下列倒序排列
a[0]和a[4]交换;a[1]和a[3]交换;a[3]处在中间位置,顺序不发生改变
#include<stdio.h>
int main()
{
int i;
int a[5];
for(i = 0; i < 5; i++)//为数组元素赋值
{
printf("a[%d]:", i);
scanf("%d", &a[i]);
}
for(i = 0; i < 2; i++)//进行倒序排列
{
int temp = a[i];
a[i] = a[4 - i];//交换a[i] 和a[4 - i]的数值
a[4 - i] = temp;
}
puts("进行倒序排列");
for(i = 0; i < 5; i++)
{
printf("[%d]=%d\n", i, a[i]);
}
return 0;
}
想要交换两个变量的值就必须引入一个中间变量来进行交换。
1.把a的值保存在temp中。
2.把b的值赋值给a。
3.把temp保存的值赋值给b。
不可以像下面一样进行赋值:
a = b; b = a;这样a和b的值都会变为b的初始值。
使用数组进行成绩处理
#include<stdio.h>
int main()
{
int i;
int sum;//5名学生分数的总和
int tensu[5];//5名学生的分数
for(i = 0; i < 5; i++)
{
printf("%2d号:", i + 1);
scanf("%d", &tensu[i]);
sum += tensu[i];
}
printf("总分:%5d\n", sum);
printf("平均分:%5.1f\n", double(sum) / 5);
return 0;
}
在这里我们仅仅是对5人的成绩进行运算,但是编写完程序后人数增加到8人呢?80人呢?800人呢?
在这里我们需要进行选择性替换(只替换需要替换的部分)
对象式宏
我们可以用对象式宏来解决上述问题
#include<stdio.h>
#define NUMBER 10//学生人数
int main()
{
int i;
int sum;//10名学生分数的总和
int tensu[NUMBER];//10名学生的分数
printf("请输入%d个学生的分数\n", NUMBER);
for(i = 0; i < NUMBER; i++)
{
printf("%2d号:", i + 1);
scanf("%d", &tensu[i]);
sum += tensu[i];
}
printf("总分:%5d\n", sum);
printf("平均分:%5.1f\n", double(sum) / NUMBER);
return 0;
}
该程序的关键部分是#define指令
#define a b 将该指令的a替换为b
在这里,a称为宏名。为了易于与变量名区分我们通常用大写字母来表示。
在本程序中,宏名为NUMBER,被替换为10.
在程序中使用宏,不仅能在一个地方进行统一管理,而且通过为常量定义名称还可以使程序更加易读,如果再加上注释,效果更明显。
程序中的10等常量被称为幻数(不清楚具体表示什么值),引入对象式宏后就可以消除程序中的幻数了。另外使用宏可以提高程序的质量。
注意
不要在程序中直接使用数值,最好通过宏的形式定义出它们的名称。定义宏的时候不要忘记加上注释!
数组元素的最大值和最小值
我们来求出分数大最大值和最小值,即数组元素的最大和最小值
#include<stdio.h>
#define NUMBER 10//学生人数
int main()
{
int i;
int tensu[NUMBER];//5名学生的分数
int max, min;
printf("请输入%d个学生的分数\n", NUMBER);
for(i = 0; i < NUMBER; i++)
{
printf("%2d号:", i + 1);
scanf("%d", &tensu[i]);
}
min = max = tensu[0];
for(i = 0; i < NUMBER; i++)
{
if(tensu[i] > max) max = tensu[i];
if(tensu[i] < min) min = tensu[i];
}
printf("最高分:%d", max);
printf("最低分:%d", min);
return 0;
}
赋值表达式的判断
对于数值类型的判断我们在前面的数据类型讲到过,现在我们来看看什么是赋值表达式的判断?
在赋值时的判断结果中,与赋值后做操作数的类型和值相同,例如int n=2.22判断结果为n=2.
对于上面求最大值、最小值中由于赋值运算符=,具有结合性,所以可以看为
min = (max = tensu[0])
例如tensu[0]=20,那么min和max和值都为20.
C语言经常使用这样的赋值方法,如a = b =0就可以把0同时赋值给a和b,但是对于初始值的声明并不适用。
比如,int a = b = 0;不可这样进行初始化
应该这样,int a = 0, b = 0;当然也可以分开声明。
我们把上面求求最大值的流程来写出来:
求tensu[0]—tensu[4]的最大值:
max = tensu[0];
if(tensu[1] > max) max = tensu[1];
if(tensu[2] > max) max = tensu[2];
if(tensu[3] > max) max = tensu[3];
if(tensu[4] > max) max = tensu[4];
对与求最小值的流程也是一样这里我们便不再赘述了。
数组的元素个数
虽然通过定义宏来变更数组元素个数十分简单,但是每次都需要进行更改重新编译后执行,因此我们可以定义出一个较大的数组,从开头取出我们需要的部分。我们来对求学生分数进行下更改
#include<stdio.h>
#define NUMBER 80//人数上限
int mian()
{
int i, j;
int sum;//学生人数
int tensu[NUMBER];//学生分数
int bunpu[11] = {0};
printf("请输入学生人数");
do
{
scanf("%d", &sum); //选择学生的人数在复合的规定内
if(sum < 1 || sum > NUMBER)
{
printf("请输入1—%d的数", NUMBER);
}
}while(sum < 1 || sum > NUMBER);
printf("请输入学生的人数:%d\n", sum);
for(i = 0; i < sum; i++)
{
printf("%2d号:", i + 1);
do
{
scanf("%d", &tensu[sum]); //输入学生成绩在1—100内
if(tensu[sum] < 0 || tensu[sum] > 100)
{
printf("\a请输入1—100内的数值:\n");
}
}while(tensu[sum] < 0 || tensu[sum] > 100);
bunpu[tensu[i] / 10]++;
}
puts("-----分布图-----");
printf(" 100:");
for(j = 0; j < bunpu[10]; j++)//100分的分布图
{
putchar('*');
putchar('\n');
}
for(j = 0; j < bunpu[10]; j++)//不到100分的分布图
{
printf("%3d - %3d:", i * 10, i * 10 + 9);
putchar('*');
putchar('\n');
}
return 0;
}
在本程序中,我们使用了int[11]数组bunpu来存放分数的分布。
求分布的表达式较为复杂,利用整数/整数舍去小数部分来进行递增的,如下
tensu[i] 为0—9时,bunpu[0]递增
tensu[i] 为10—19时,bunpu[1]递增
……………………………………
tensu[i] 为80—89时,bunpu[8]递增
tensu[i] 为90—99时,bunpu[9]递增
tensu[i] 为100时,bunpu[10]递增
通过上述循环,tensu[i]的分数就保存在数组bunpu中了。
结语
数组就是我们向内存访问请求存放数据内存的地方,然后我们通过数组的声明为其确定类型、名称,再通过初始化后,通过进行下表运算符就可以对数组进行访问使用了,当然我们还可以不进行初始化,通过使用for循环对数组进行挨个赋值,再进行数组的遍历就可以使用了。
创建好数组后一般不能更改数组元素的个数,但是我们可以通过对象式宏来进行任意的对数组元素进行更改。
最后,天气渐冷,大家一定要做好保暖措施,锻炼身体,预防流感!