乐趣区

关于c: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 <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. 字符数组的输入输出

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

  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 <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) 比拟字符串的一个简略规定:在英文字典中地位靠后的为大。该函数的返回后果:

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

留神:

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

Reference:

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

退出移动版