# C数组
C 语言支持**数组**数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 numbers\[0\]、numbers\[1\]、...、numbers\[99\] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
![](https://box.kancloud.cn/2015-12-13_566d2e1e9fb32.jpg)
## 声明数组
在 C 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
~~~
type arrayName [ arraySize ];
~~~
这叫做一维数组。**arraySize**必须是一个大于零的整数常量,**type**可以是任意有效的 C 数据类型。例如,要声明一个类型为 double 的包含 10 个元素的数组**balance**,声明语句如下:
~~~
double balance[10];
~~~
现在*balance*是一个可用的数组,可以容纳 10 个类型为 double 的数字。
## 初始化数组
在 C 中,您可以逐个初始化数组,也可以使用一个初始化语句,如下所示:
~~~
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
~~~
大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 \[ \] 中指定的元素数目。
如果您省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果:
~~~
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
~~~
您将创建一个数组,它与前一个实例中所创建的数组是完全相同的。下面是一个为数组中某个元素赋值的实例:
~~~
balance[4] = 50.0;
~~~
上述的语句把数组中第五个元素的值赋为 50.0。所有的数组都是以 0 作为它们第一个元素的索引,也被称为基索引,数组的最后一个索引是数组的总大小减去 1。以下是上面所讨论的数组的的图形表示:
![](https://box.kancloud.cn/2015-12-14_566e449008415.jpg)
## 访问数组元素
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:
~~~
double salary = balance[9];
~~~
上面的语句将把数组中第 10 个元素的值赋给 salary 变量。下面的实例使用了上述的三个概念,即,声明数组、数组赋值、访问数组:
## 实例
```
#include <stdio.h>
int main ()
{
int n[ 10 ]; /* n 是一个包含 10 个整数的数组 */
int i,j;
/* 初始化数组元素 */
for ( i = 0; i < 10; i++ )
{
n[ i ] = i + 100; /* 设置元素 i 为 i + 100 */
}
/* 输出数组中每个元素的值 */
for (j = 0; j < 10; j++ )
{
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
```
当上面的代码被编译和执行时,它会产生下列结果:
~~~
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
~~~
数组练习:
1 将数组A中的内容和数组B中的内容进行交换。(数组长度相同)
2 计算一个数组中数字的最大值最小值及其所在的位置
3 有一个有序的数组,用户输入一个数字k,将k插入数组。要求插入后数组依然有序
4 用数组保存 Fibonacci 数列的前20项,以5个数为一行的形式输出
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597
5 数组中存储学生成绩,计算该班级最高分,最低分,平均分,及格人数(60分以上)
成绩用户输入 当用户输入-1 表示输入结束
6 用户输入5个数,将其反序输出
7 用户输入5个数,将其翻转后输出
8 用户输入一串字符,统计单词的数量
# 冒泡排序法
在实际开发中,有很多场景需要我们将数组元素按照从大到小(或者从小到大)的顺序排列,这样在查阅数据时会更加直观,例如:
* 一个保存了班级学号的数组,排序后更容易分区好学生和坏学生;
* 一个保存了商品单价的数组,排序后更容易看出它们的性价比。
对数组元素进行排序的方法有很多种,比如冒泡排序、归并排序、选择排序、插入排序、快速排序等,其中最经典最需要掌握的是「冒泡排序」。
以从小到大排序为例,冒泡排序的整体思想是这样的:
* 从数组头部开始,不断比较相邻的两个元素的大小,让较大的元素逐渐往后移动(交换两个元素的值),直到数组的末尾。经过第一轮的比较,就可以找到最大的元素,并将它移动到最后一个位置。
* 第一轮结束后,继续第二轮。仍然从数组头部开始比较,让较大的元素逐渐往后移动,直到数组的倒数第二个元素为止。经过第二轮的比较,就可以找到次大的元素,并将它放到倒数第二个位置。
* 以此类推,进行 n-1(n 为数组长度)轮“冒泡”后,就可以将所有的元素都排列好。
整个排序过程就好像气泡不断从水里冒出来,最大的先出来,次大的第二出来,最小的最后出来,所以将这种排序方式称为
下面我们以“3 2 4 1”为例对冒泡排序进行说明。
第一轮 排序过程
3 2 4 1 (最初)
2 3 4 1 (比较3和2,交换)
2 3 4 1 (比较3和4,不交换)
2 3 1 4 (比较4和1,交换)
第一轮结束,最大的数字 4 已经在最后面,因此第二轮排序只需要对前面三个数进行比较。
第二轮 排序过程
2 3 1 4 (第一轮排序结果)
2 3 1 4 (比较2和3,不交换)
2 1 3 4 (比较3和1,交换)
第二轮结束,次大的数字 3 已经排在倒数第二个位置,所以第三轮只需要比较前两个元素。
第三轮 排序过程
2 1 3 4 (第二轮排序结果)
1 2 3 4 (比较2和1,交换)
至此,排序结束。
## 算法总结及实现
对拥有 n 个元素的数组 R\[n\] 进行 n-1 轮比较。
第一轮,逐个比较 (R\[1\], R\[2\]), (R\[2\], R\[3\]), (R\[3\], R\[4\]), ……. (R\[N-1\], R\[N\]),最大的元素被移动到 R\[n\] 上。
第二轮,逐个比较 (R\[1\], R\[2\]), (R\[2\], R\[3\]), (R\[3\], R\[4\]), ……. (R\[N-2\], R\[N-1\]),次大的元素被移动到 R\[n-1\] 上。
。。。。。。
以此类推,直到整个数组从小到大排序。
具体的代码实现如下所示:
```
~~~
#include <stdio.h>
int main(){
int nums[10] = {4, 5, 2, 10, 7, 1, 8, 3, 6, 9};
int i, j, temp;
//冒泡排序算法:进行 n-1 轮比较
for(i=0; i<10-1; i++){
//每一轮比较前 n-1-i 个,也就是说,已经排序好的最后 i 个不用比较
for(j=0; j<10-1-i; j++){
if(nums[j] > nums[j+1]){
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
//输出排序后的数组
for(i=0; i<10; i++){
printf("%d ", nums[i]);
}
printf("\n");
return 0;
}
~~~
运行结果:
1 2 3 4 5 6 7 8 9 10
```
- 空白目录
- 第一章 c语言简介
- 1 通俗地理解什么是编程语言
- 2 C语言究竟是一门怎样的语言
- 第二章 算法简介&基本语法
- 1 算法简介
- 2 C 程序结构
- 3 C 基本语法
- 第三章 数据类型
- 1 数据类型
- 2 变量
- 3 常量
- 第四章 运算符
- 1 算术运算符
- 2 关系运算符
- 3 逻辑运算符
- 4 位运算符
- 5 赋值运算符
- 6 杂项运算符(其他运算符)
- 7 c语言中的运算符优先级
- 第五章 控制流
- 1 判断语句
- 2 switch语句
- 3 循环语句
- 4 流程控制相关案例
- 第六章 指针
- 1 c语言指针概述
- 2 指针的算术运算
- 3 指针数组
- 4 指向指针的指针
- 5 传递指针给函数
- 6 从函数返回指针
- 第七章 函数
- 1 函数的语法
- 2 作用域规则
- 3 形参与实参
- 第八章 数组
- 1 C语言中的数组
- 2 多维数组
- 3 传递数组给函数
- 4 从函数返回数组
- 第九章 指针
- 1 分钟彻底理解C语言指针的概念
- 2 C语言指针变量的定义和使用
- 3 C语言指针变量的运算(加法、减法和比较运算)
- 4 C语言数组指针(指向数组的指针)
- 5 C语言字符串指针(指向字符串的指针)
- 第十章 结构体
- 第十一章 练习
- 第十二章 文件操作
- 第十三章 文件操作2