数组的概念和定义

一组数据的集合称为数组(Array),它所包含的每一个数据叫做数组元素(Element),所包含的数据的个数称为数组长度(Length)。

数组的定义格式为

1
type arrayName[length]

type 为数据类型,arrayName 为数组名,length 为数组长度。 需要注意的是:

数组长度 length 最好是常量表达式,例如 10、20_4 等,这样在所有编译器下都能运行通过;如果 length 中包含了变量,例如 n、4_m 等,在某些编译器下就会报错。

数组是一个整体,它的内存是连续的;也就是说,数组元素之间是相互挨着的,彼此之间没有一点点缝隙。

一般情况下,数组名会转换为数组的地址,需要使用地址的地方,直接使用数组名即可。

访问数组元素的格式为:

1
arrayName[index]

index 为数组下标。注意 index 的值必须大于等于零,并且小于数组长度,否则会发生数组越界。

数组的内存结构

数组在内存中是连续存储的内存空间,空间地址是连续的,并且每个数组元素所占内存大小一致。

字符数组和字符串

字符数组即字符的数组:

1
2
3
4
char a[10];  //一维字符数组
char b[5][10]; //二维字符数组
char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 给部分数组元素赋值
char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' }; //对全体元素赋值时可以省去长度

字符数组实际上是一系列字符的集合,也就是字符串(String)。在C语言中,没有专门的字符串变量,没有string类型,通常就用一个字符数组来存放一个字符串。

C语言规定,可以将字符串直接赋值给字符数组,例如:

1
2
char str[30] = {"lautung.com"};
char str[30] = "lautung.com"; //这种形式更加简洁,实际开发中常用

字符数组只有在定义时才能将整个字符串一次性地赋值给它,一旦定义完了,就只能一个字符一个字符地赋值了。请看下面的例子:

1
2
3
4
5
char str[7];
str = "abc123"; //错误
//正确
str[0] = 'a'; str[1] = 'b'; str[2] = 'c';
str[3] = '1'; str[4] = '2'; str[5] = '3';

字符串结束标志

在C语言中,字符串总是以’\0’作为结尾,所以’\0’也被称为字符串结束标志,或者字符串结束符。

‘\0’是 ASCII 码表中的第 0 个字符,英文称为 NUL,中文称为“空字符”。该字符既不能显示,也没有控制功能,输出该字符不会有任何效果,它在C语言中唯一的作用就是作为字符串结束标志。

由” “包围的字符串会自动在末尾添加’\0’。例如,”abc123”从表面看起来只包含了 6 个字符,其实不然,C语言会在最后隐式地添加一个’\0’

字符串长度

所谓字符串长度,就是字符串包含了多少个字符(**不包括最后的结束符’\0’**)。

使用string.h头文件中的 strlen() 函数来求字符串的长度:

1
length strlen(strname);

字符串的输入和输出

字符串的输出

  • puts():输出字符串并自动换行,该函数只能输出字符串
  • printf():通过格式控制符%s输出字符串,不能自动换行。除了字符串,printf() 还能输出其他类型的数据。

字符串的输入

  • scanf():通过格式控制符%s输入字符串。除了字符串,scanf() 还能输入其他类型的数据。
  • gets():直接输入字符串,并且只能输入字符串。

C语言数组是静态的

数组一旦被定义后,占用的内存空间就是固定的,容量就是不可改变的,既不能在任何位置插入元素,也不能在任何位置删除元素,只能读取和修改元素,我们将这样的数组称为静态数组。

变长数组

变量的值在编译期间并不能确定,只有等到程序运行后,根据计算结果才能知道它的值到底是什么,所以数组长度中一旦包含了变量,那么数组长度在编译期间就不能确定了,也就不能为数组分配内存了,只有等到程序运行后,得到了变量的值,确定了具体的长度,才能给数组分配内存,我们将这样的数组称为变长数组(VLA, Variable Length Array)。

普通数组(固定长度的数组)是在编译期间分配内存的,而变长数组是在运行期间分配内存的。