为了有效处理大批量数据,引入数组(array):
- 数组是一组有序数据的集合。数组中各数据的排列是有规律的,下标(subscript)代表数据在数组中的序号。
- 用一个数组名和下标来唯一确定数组中的元素。
- 数组中的每一个元素都属于同一数据类型。不同数据类型的数据不能放入同一个数组。
一、一维数组
一维数组是数组中最简单的,只需用一个下标就能唯一确定其中的元素。
1. 定义一维数组
定义一维数组的一般形式为:
类型说明符 数组名[常量表达式];
说明:
- 数组定义时需要指定数组中元素的个数,方括号中的
常量表达式
用来表示元素的个数,即数组的长度。 常量表达式
可以包含常量和符号常量,但不能时变量,C 语言不允许对数组的长度作动态定义。
2. 一维数组的初始化
在定义数组的同时可以给数组中的元素赋值,称为数组的初始化。
- 定义数组时对全部元素初始化:
int a[5] = {1, 2, 3, 4, 5};
- 只给一部分元素初始化:
int a[5] = {1, 2, 3};
花括号内只提供了 3 个初始值,表示给前三个元素赋值,系统自动为后面两个元素赋值为 0。
- 若对数组初始化时提供的数据个数与数组长度相同,可以不指定数组长度:
int a[] = {1, 2, 3, 4, 5};
定义数组时未被初始化的数组,如果是整数型数组,系统自动将其初始化为 0;如果是字符型数组,初始化为\0
;如果是指针型数组,初始化为NULL
,即空指针。
3. 引用一维数组
使用数组名和下标引用数组中的元素:
数组名[下标];
注意:下标是从 0 开始的,只能引用数组元素而不能一次整体调用整个数组全部元素的值。
#include
int main()
{
int a[5], i, j, t;
for (i = 0; i < 5; i++)
scanf("%d", &a[i]);
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5 - i; j++)
{
if (a[j] > a[j + 1])
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
for (i = 0; i < 5; i++)
printf("%d\t", a[i]);
return 0;
}
二、二维数组
二维数组常称为矩阵(matrix),可以将其直观写成行(row)和列(column)的排列形式。
1. 定义二维数组
二维数组的定义与一维数组相似:
类型说明符 数组名[常量表达式][常量表达式];
例如,float a[3][4]
定义了一个 3 行 4列的二维数组,数组元素是浮点数。在 C 语言中,二维数组中元素的排列顺序是按行存放的,即在内存中存满一行后,在填充到下一行。
C 语言还允许定义多维数组,定义与使用方法与二维数组相似。
2. 引用二维数组
二维数组中元素的表示方式与一维数组类似,只不过多了一个下标。
数组名[下标][下标];
下标必须在数组定义的大小范围内。下标均从 0 开始计数。
3. 二维数组的初始化
- 分行给二维数组赋初始值:
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
- 可以将所有数据写在一个花括号内,按数组元素在内存中的顺序对各元素赋值:
int a[2][3] = {1, 2, 3, 4, 5, 6};
- 对部分元素赋初始值,其余元素自动为 0:
int a[2][3] = {{1}, {4}}; // 只给各行第一列的元素赋值
- 如果对全部元素赋初始值,则可以不指定第一维的长度(系统自动推断),但第二维长度不能省略:
int a[][3] = {1, 2, 3, 4, 5, 6};
三、字符数组
C 语言中没有字符串类型,也没有字符串变量,字符串都是放在一个字符型数组中的。
1. 定义字符数组
定义字符数组的方法与定义数值型数组的方法类似。
char c[10];
int c[10]; // 合法但浪费存储空间
2. 字符数组的初始化
初始化字符数组时,提供的初始值数量必须小于或等于数组长度。若初始值数量小于数组长度,系统自动为后面的元素赋值为空字符\0
。若初始值数量对于数组长度,在定义数组时可以省略数组长度。
char c[5] = {'a' ,'0', ' ', ';', '['};
char d[2][3] = {{'q', 'w', 'e'}, {'r', 't', 'y'}};
3. 字符数组的引用
字符数组的引用同数值型一维数组和二维数组。
4. 字符串
C 语言是将字符串作为字符数组来处理的,字符串的实际长度与数组长度相同。但在实际工作中,我们通常更关心字符串的有效长度而不是字符数组的长度。
为了得到字符串实际长度,C 语言规定了一个字符串结束标志,以字符\0
作为结束标志。在字符数组中,遇到字符\0
时表示字符串结束,把它前面的字符组成一个字符串。C 语言系统会在字符串数组储存字符串常量时自动加一个\0
作为结束符,因此所占的存储空间会比原数组多一个字节。
于是我们可以用字符串常量来使字符数组初始化。
char c[] = {"Hello World"};
char c[] = "Hello World"; // 可以省略花括号
char c[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W',' o', 'r', 'l', 'd', '\0'}
5. 字符数组的输入输出
字符数组的输入输出有两种方法:
- 用格式符
%c
逐个输入输出单个字符。 - 用格式符
%s
一次性输入输出这个字符串。
char str[10];
scanf("%s", str);
printf("%s", str);
注意:scanf()
函数中的输入项如果是字符数组名,不要再加地址符%
,因为在 C 语言中,数组名就代表该数组第一个元素的地址(或者说数组的起始地址)。
由于系统把空格字符作为输入的字符串之间的分隔符,因此当输入多个字符串时,因以空格分隔;如果输入的字符串中有空格,应该将其分配给不同的变量,或者直接使用gets()
函数输入。
6. 字符串处理函数
C 语言的函数库提供了一些专门处理字符串的函数:
puts(str)
:输出字符串。gets(str)
:输入字符串。strcat(str1, str2)
:字符串连接函数。将str2
连接到str1
的后面,返回str1
的地址。strcpy(str1, str2)
:字符串复制函数。将str2
复制给str1
.strncpy(str1, str2, n)
:字符串复制函数。将str2
前n
个字符赋值给str1
。strcmp(str1, str2)
:字符串比较函数。逐个字符比较,以第 1 对不相同的字符的比较结果为准。strlen(str)
:字符串长度函数。返回字符串str
的真实长度(不包括\0
)。strlwr(str)
:转为小写的函数。strupr(str)
:转为大写的函数。
以上函数的具体用法如下:
#include
#include
int main()
{
char s1[100], s2[100] = "Hello ", s3[100];
gets(s1);
puts(s1);
printf("%s\n", strcat(s2, s1));
puts(s2);
strcpy(s3, s2);
puts(s3);
printf("%d\n", strcmp(s1, s2));
printf("%d\n", strlen(s3));
printf("%s\n", strlwr(s3));
printf("%s\n", strupr(s3));
return 0;
}
// GVenusLeo
// GVenusLeo
// Hello GVenusLeo
// Hello GVenusLeo
// Hello GVenusLeo
// -1
// 15
// hello gvenusleo
// HELLO GVENUSLEO
使用strcmp(str1, atr2)
比较字符串的一个简单规则:在英文字典中位置靠后的为大。该函数的返回结果:
- 若
str1
与str2
相同,则返回值为 0。 - 若
str1
大于str2
,则返回值是一个正数。 - 若
str1
小于str2
,则返回值是一个负数。
注意:
- 不能用赋值语句直接给字符数组赋值,因为字符数组名是一个地址常量,不能赋值给一个字符型变量或字符数组元素。同理,不能直接比较两个字符串的大小。下面的语句不合法的:
str1 = "China";
str2 = str1;
str1 > str2;
- 使用这些函数前应在程序文件的开头引入相应的头文件:
#include
Reference: