数组(一)
引言
什么是数组?
打个比方,比如说你手头有数以千计或数以万计的数字需要存储,难道你想要采取下面这种方法嘛?
int a = 1,b = 2,c = 3 ……
显然,这让自己感到疲惫,也让被人觉得“我”太愚蠢了。所以为了方便**数组(array)**这个东西就应运而生。
在C++中一个数组的样子是这个样子的:
int a[10];
/*
int 代表的是数组里的东西是整数类型的,a就是这个数组的名字,而[10]里的10,指的就是里面可以有10个int型数字
*/
数组可以存什么?
在上一个代码段中我们可以看到,在定义数组的时候我们先注明了数组的类型,也就是说在数组中所有的东西都是同一种类型,我们可以这样总结:数组是同种数据的集合。比如:
int a[3]={1,2,3}
/*
这里面存有三个整型数字
*/
定义和引用数组
定义一维数组
来看一看较为官方的版本: 类型名 数组名[常量表达式];
这就是我们刚刚拿出来举得例子:int a[10];
int 就是指类型名,a就是数组的名字,10就是我们的常量表达式。
但是定义数组的语句可远远不止这么一点,比如:
int a[2*5];
int a[n*2]; //假设n在前面定义过
总结一点就是在"[ ]"中,只允许常量的存在,哪怕是之前定义过的变量比如n,哪怕是再复杂的表达式。但是如果’’[ ]'里面是变量,那就会报错啦,比如:
int n;
cin >> n;
int a[n];
/*
这样就大错特错啦!
可以改为:
const int n = 5;
*/
我们之后还会遇到这样的数组形式:int a[];
这个"[ ]“里面空空如也,但是不要小瞧它,虽然”[ ]“什么都没有,但是如果数组里面来”货“啦,”[ ]"里面的数值会自动变化的(虽然肉眼不可见),比如:
int a[] = {1,2,3};
/*
[]里面不可见的数字为3,因为我们给了它三个数字。
*/
引用一维数组
当然,要想引用前提是我们已经定义过数组了,比如:int a[3];
在这里我们知道"[ ]“里面的3指的是这个数组里存在三个东西,这是我们在定义时“3”代表的意思,但是在我们引用数组的时候”[ ]"里面的数字又换了一个意思,先上例子:
#include <iostream>
using namespace std;
int main()
{
int a[3] = { 1,2,3 };
cout << a[2];
}
/*
结果输出的为3
*/
为什么呢?a[2]
不应该输出的是“2”嘛?答案是不是的,因为数组在被引用的时候"[ ]"里面数字被称之为下标,而下标与数组元素的对应关系是这样的:
下标 | 元素 |
---|---|
0 | 1 |
1 | 2 |
2 | 3 |
哦!原来下标是从0开始的!没错这确实有点不符合中国人的使用习惯,因为我们都是从1开始数数的。
下面让我们来实践一个小例子:
/*
定义一个整形数组a,把0~9共10个整数赋给数组元素a[0]~a[9],然后按照a[9]、a[8]、……、a[0]输出
*/
#include <iostream>
using namespace std;
int main()
{
int i,a[10];
for (i = 0; i < 10; i++) {
a[i] = i;
}
for (i = 9; i >= 0; i--) {
cout << a[i] << " ";
}
}
输出结果为:9 8 7 6 5 4 3 2 1
解析:
int i,a[10]; //定义了一个变量i,和一个存放有10个整形元素的数组,数组名字为a
for (i = 0; i < 10; i++) {
a[i] = i;
} //从0到9的for循环,功能是为了让0赋给a[0],1赋给a[1]……9赋给a[9].
for (i = 9; i >= 0; i--) {
cout << a[i] << " ";
} //从9到0的for循环,功能是为了从a[9]输出到a[0].
(这里注意循环结束的判断👀)
一维数组初始化
对于初始化数组我们有如下几种方法:
-
在定义数组时:
int a[3] = {1,2,3};
-
在定义时部分赋初值:
int a[100] = {1,2,3};
-
定义时不定长赋值:
int a[] = {1,2,3};
程序例题:
- 用数组来求Fibonacci数列问题。
/*求Fibonacci数列前二十项*/
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int i;
int f[20] = { 1,1 };
for (i = 2; i < 20; i++) {
f[i] = f[i - 1] + f[i - 2]; //利用Fibonacci数列的特点
}
/*输出控制*/
for (i = 0; i < 20; i++) {
if (i % 5 == 0)cout << endl; //每5个元素项目后换行
cout << setw(8) << f[i]; //设置间距
}
}
1 1 2 3 5
8 13 21 34 55
89 144 233 377 610
987 1597 2584 4181 6765
- 编写程序,用冒泡排序法对10个数进行排序。
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a[11];
int i, j ;
cout << "请输入你想要的10个进行排序的数字:" << endl;
for (i = 1; i < 11; i++) {
cin >> a[i];
}
cout << endl;
for (j = 1; j <= 9 ; j++)
{
for (i = 1; i <= 10 - j; i++) //a[0]不用它
{
if (a[i] > a[i + 1])
{
int t = a[i]; a[i] = a[i + 1]; a[i + 1] = t;
}
}
}
cout << "排序后为:" << endl;
for (i = 1; i < 11; i++) {
cout << a[i] << setw(4);
}
}
请输入你想要的10个进行排序的数字:
-1 2 3 4 5 6 7 34 32 12
排序后为:
-1 2 3 4 5 6 7 12 32 34
分析:
for (j = 1; j <= 9 ; j++)
{
for (i = 1; i <= 10 - j; i++)
{
if (a[i] > a[i + 1])
{
int t = a[i]; a[i] = a[i + 1]; a[i + 1] = t;
}
}
}
/*
对于双层循环,脑子里一定要建立大循环与小循环的概念,从最外层的大循环我们可以看出大循环执行了9次,而外层循环中的内层循环随着外层大循环执行一次它每一次都少执行一次。
上一段话讲述的非常抽象,我们先看一看内层循环的功能吧,如果前面一个数字大与后面一个数字那就让大的跑到后面,利用循环语句重复执行,大的数字就沉底了!
现在明白为什么内存循环为什么执行10-i次了,既然每一次大的后跑到后面去了,那么我们在之后的对比就不用管它了!
*/