为了无效解决大批量数据,引入数组(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 <stdio.h>
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 <stdio.h>
#include <string.h>
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 <string.h>
Reference:
谭浩强《C 程序设计(第五版)》