[C程序设计] 06 - 数组

为了有效处理大批量数据,引入数组(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. 字符数组的输入输出

字符数组的输入输出有两种方法:

  1. 用格式符%c逐个输入输出单个字符。
  2. 用格式符%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):字符串复制函数。将str2n个字符赋值给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)比较字符串的一个简单规则:在英文字典中位置靠后的为大。该函数的返回结果:

  • str1str2相同,则返回值为 0。
  • str1大于str2,则返回值是一个正数。
  • str1小于str2,则返回值是一个负数。

注意:

  • 不能用赋值语句直接给字符数组赋值,因为字符数组名是一个地址常量,不能赋值给一个字符型变量或字符数组元素。同理,不能直接比较两个字符串的大小。下面的语句不合法的:
str1 = "China";
str2 = str1;
str1 > str2;
  • 使用这些函数前应在程序文件的开头引入相应的头文件:
#include 

Reference:

谭浩强《C程序设计(第五版)》

你可能感兴趣的:(c)