【C语言入门教程】4.1 一维数组
数组与指针涉及到数据在内存中的存储位置问题,数组由连续的存储单元组成,最低地址对应于数组的第一个单元,最高地址对应于数组的最后一个单元。指针是一种特殊的变量,该变量所存放的是内存地址,通过指针变量可访问所指向内存空间的内容。
4.1 一维数组
数组是一组相关的内存位置,它们都具有相同对的名称和类型。为引用数组中的特定位置或元素,需要指定数组名称和数组中特定的元素的位置编号,该编号即是数组下标。一维数组是只使用一组下标表示的数组。
4.1.1 一维数组的一般形式
一维数组的一般声明形式为:
数据类型 数组名[长度];
其中长度必须是常量表达式,数组名与其他变量名称一样,只能包含字母、数字和下滑线,且不能以数字字符开始。如下列所示,声明 10 个元素的字符型数组。
char c[10]; // 声明数组 c ,类型为字符型,长度为 10
该数组的第一个元素为 c[0],第 n 个元素为 c[n-1]。为数组初始化有 3 种方式,第一种
是根据数组小标逐个初始化,如
int i; for (i = 0; i < 10; i++) { c[i] = 0; }
数组初始化的第二种方式是通过在声明时加入等号以及逗号分开的初始值列表,如:
char c[10] = { 63, 64, 65, 67, 68 ,69, 70, 71, 72 }; // 声明数组并初始化
如果初始值少于数组中的元素,则剩余元素将初始化为 0。如下列所示,将数组的所有元素都初始化为 0。数组初始化的第三种方式是声明时不指定数组长度,根据初始值的个数来决定数组长度,如:
char c[] = { 63, 64, 65, 67, 68 ,69, 70, 71, 72 }; // 声明数组并初始化,数组长度为 10
声明后,数组元素顺序存放于内存中,假设起始地址为 3001,则每个数组元素依次加 1,如下图所示:
数组元素 | 值 | 内存地址 |
高位
低位 |
c[0] | 63 | 3001 | |
c[1] | 64 | 3002 | |
c[2] | 65 | 3003 | |
c[3] | 66 | 3004 | |
c[4] | 67 | 3005 | |
c[5] | 68 | 3006 | |
c[6] | 69 | 3007 | |
c[7] | 70 | 3008 | |
c[8] | 71 | 3009 | |
c[9] | 72 | 300A |
使用数组时,可通过数组小标引用每个数组元素。如下列所示,使用选择排序法对数据的元素进行从小到大排序。
#include <stdio.h> // 调用基本输入输出函数 #include <stdlib.h> // 调用常用函数库,提供生成随机数函数 int main() { int a[10]; int i, j; // 声明循环控制变量 int t; // 声明整型变量t,用于排序中交换数组元素的值 printf("排序前的数组:\n"); for (i = 0, i < 10; i++) { a[i] = rand() % 100 + 1; // 使用随机函数,生成 1 到 100 间随机数 printf("%4d ", a[i]); // 输出排序前的数组 } printf("\n排序后的数组\n"); for (i = 0, i < 9; i++) // i 从 0 循环到 8 { for (j = i + 1; j < 10; j++) // j 从 i + 1 循环到 9 { if (a[i] > a[j]) // 比较的两个元素值的大小,如果前一个大于后一个,交换两个元素的值 { t = a[i]; // 将前一个元素的值保存到变量 t 中 a[i] = a[j]; // 将后一个元素的值复制到前一个元素中 a[j] = t; // 将变量 t 所保存的值,复制到后一个元素中 } } } for (i = 0; i < 10; i++) { printf("%4d", a[i]); // 输出排序后的数组 } return 0; // 退出程序 }
代码中,rand()函数用于生成整型伪随机数序列,将所生成的随机数用 n 取模再加上 1 ,则可将随机数的范围限定在 1 至 n 以内,这是一种常用的算法。选择排序法使用了双层循环,外围第 1 轮循环时,将数组元素a[0] 与其他元素依次比较。如果有小于 a[0] 的元素,则将两个元素交换位置,这样就能保证 a[0] 所保存的是数列里最小的值。进入第 2 轮循环后,就不考虑 a[0],将 a[1] 与其后的元素比较,a[1] 则保存了数组中第 2 小的值。这样,没次内存循环的次数都减少了,数组内的元素被从小到大排序。
4.1.2 字符串使用的一维数组
字符型数组可以存放字符串数据,字符串数组与一般的字符数组的区别是字符串数组包含字符串结束符“\0”,该符号的 ASCII 码值为 0。因此,字符串一维数组的长度要比实际字符串的长度多 1 元素。如下列所示:
char c1[] = {'C', 'h', 'i', 'n', 'a'}; // 声明字符数组 c1,分配的长度 5 char c2[] = "China"; // 声明字符串数组 c2,分配的长度为 6
数组 c1 是字符数组,c2 是字符串数组,它们在内存中所占用的空间如下图所示:
c1 | c2 |
C | C |
h | h |
i | i |
n | n |
a | a |
\0 |
字符数组 与 字符串数组 在内存中所占用的空间
C 语言并没有将字符串作为独立的数据类型,但允许使用字符串常量和字符串数组,并在标准函数库里提供了一些常用的字符串操作函数。最常用的字符串操作函数如下表所示:
最常用的字符串操作函数 | |
函数名 | 说 明 |
strcpy(s1, s2) | 将 s2 复制到 s1 |
strcat(s1, s2) | 将 s2 连接到 s1 的末尾 |
strlen(s1) | 返回 s1 的长度 |
strcmp(s1, s2) | 比较两个字符串,若 s1 与 s2 相等,返回值为 0;若 s1 < s2,返回值小于 0;若 s1 > s2,返回值大于 0 |
注意:只有包含字符串结束符的数组才被认为是字符串数组,字符数组则不能被函数当着字符串操作。