数组

维基百科,自由的百科全书
跳转至: 导航搜索

数组是電腦编程语言上,對於「Array」的中文稱呼。它十分類似数学上的「矩阵」, 但是在電腦編程語言上,表示方法和意義上略有不同。

數學上的矩阵看起來像這樣:


a=\begin{bmatrix} 3 & 6 & 2 \\ 0 & 1 & -4 \\ 2 & -1 & 0\end{bmatrix}

而電腦上的数组看起來像這樣,例如C语言中的数组:

    int a[3][3]={ 
                    { 3,  6,  2 },
                    { 0,  1, -4 },
                    { 2, -1,  0 }
                 };

雖然数组在各種電腦編程語言中的表示式略有不同,但是幾乎每一種編程語言都有這種結構和觀念,它已經不只是一種編程專用的術語,而是電腦運作中非常重要的技術和概念。當前電腦能夠顯示、打印中文字,都是数组的觀念應用;字串也是基於數組的一種重要數據結構。数据库也是数组概念的一種擴充和延伸。

语义[编辑]

数组概念有双重含义,一是数据类型,二是实体(entity)。C语言标准中规定,一个数组类型描述了连续分配的非空的具有特定元素对象类型的对象集合。这些元素对象的类型称为元素类型(element type)。数组类型由元素类型与元素的数目确定。[1]

在C语言中,可以显式定义一个数组类型,例如:

 typedef int myArrayType [101];

数组名作为数组实体的标识符,具有特殊性,不同于整型、浮点型、指针型或结构类型等变量标识符。这是因为数组是一组元素的聚集,不能把一个聚集看作一个值直接读出(即右值),也不能把一个聚集看作一个地址直接赋值(即左值)。因此,数组名作为左值、右值,在C语言标准中都有特殊规定:[2]

  • 作为sizeof的操作数,数组名代表数组对象本身;
  • 作为酉算子&的操作数,数组名代表数组对象本身;[3]
  • 作为字符串字面量用于初始化一个数组;
  • 其他情形,表达式中的数组名从数组类型被转化为指向数组首元素的指针类型表达式(右值)。[4]

例如,

char s[]="hello";
 
int main() {
  char (*p1)[6]=&s; //OK!
  char (*p2)[6]=s; //compile error: cannot convert 'char*' to 'char (*)[6]'   
  char *p3=&s;//compile error: cannot convert 'char (*)[6]' to 'char*' in initialization
}

根据上述C语言标准中的规定,表达式 &s 的值的类型是char (*)[6],即指向整个数组的指针;而表达式 s 则被隐式转换为指向数组首元素的指针值,即 char* 类型。同理,表达式 s[4] ,等效于表达式 *(s+4)。

数组下标运算符[编辑]

C语言标准中定义,数组下标运算(Array subscripting)有两个运算数,一个为到类型type的指针表达式,另一个运算符为整数表达式,结果为类型type。但没有规定两个运算数的先后次序。[5]因此,有以下推论:

  • 两个运算数可以交换顺序,即 p[N] 与 N[p] 是等价的,为 *(p+N) ;
  • 数组下标运算,既可以适用于数组名(实际上隐式把数组名转换为指向数组首元素的指针表达式),也可以适用于指针表达式;
  • 整型表达式可以取负值。

例如:

int a[10], *p = a;
p[0] = 10;
( p + 1 )[0] = 20;
0[p + 1] = 10;

多维数组[编辑]

普通数组采用一个整数来作下标。多维数组的概念特别是在数值计算和图形应用方面非常有用。我们在多维数组之中采用一系列有序的整数来标注,如在[ 3,1,5 ] 。这种整数列表之中整数的个数始终相同,且被称为数组的“维度”。关于每个数组维度的边界称为“维”。维度為k的数组通常被称为k维。

程式設計[编辑]

數組設計之初是在形式上依賴內存分配而成的,所以必須在使用前預先請求空間。這使得數組有以下特性:

  1. 請求空間以後大小固定,不能再改變(數據溢出問題);
  2. 在內存中有空間連續性的表現,中間不會存在其他程序需要調用的數據,為此數組的專用內存空間;
  3. 在舊式程式語言中(如有中階語言之稱的C),程式不會對數組的操作做下界判斷,也就有潛在的越界操作的風險(比如會把數據寫在運行中程式需要調用的核心部份的內存上)。

因為簡單數組強烈倚賴電腦硬件之內存,所以不適用於現代的程序設計。欲使用可變大小、硬件無關性的數據類型,Java等程式設計語言均提供了更高級的數據結構:ArrayListVector動態陣列

参见[编辑]

外部鏈接[编辑]

  1. ^ C99语言标准6.2.5节中规定:An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called “array of T”. The construction of an array type from an element type is called “array type derivation”.
  2. ^ C99标准中的第“6.3.2.1 Lvalues, arrays, and function designators”小节中规定:Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
  3. ^ 只能对具有左值的数组名执行取地址的&操作。对右值数组,则会编译报错:taking address of temporary
  4. ^ C++98标准中规定:An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T.” The result is a pointer to the first element of the array.
  5. ^ C99语言标准“6.5.2.1 Array subscripting”中有:Constraints One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.