An array is a series of elements of the same type placed in contiguous memory locations that can be individually referenced by adding an index to a unique identifier.
數組是類型相同的一組在計算機內存的連續存儲的數據集合,它們有同一個標識符,通過索引(下標)加以區別與引用。
That means that, for example, five values of type int can be declared as an array without having to declare 5 different variables (each with its own identifier). Instead, using an array, the five int values are stored in contiguous memory locations, and all five can be accessed using the same identifier, with the proper index.
也就是說,5個同一數據類型為int的值可以定義為一個數組變量,而不需要定義5個不同變量(一個變量一個變量名)。使用數組,存取數據時只要給出數組的標識符(數組名)和相應的下標即可。
For example, an array containing 5 integer values of type int called foo could be represented as
下面的例子中,一個數組包含5個元素,類型為整數類型,名稱為foo。
where each blank panel represents an element of the array. In this case, these are values of type int. These elements are numbered from 0 to 4, being 0 the first and 4 the last; In C++, the first element in an array is always numbered with a zero (not a one), no matter its length.上面空白的矩形代表數組中的一個元素。這個例子中,數據類型為Int。元素的編號從0到4,0是第一個元素,4是最後一個元素。在C++中不管數組長度多長,數組中的第一個元素下標為0。
Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:和變量的定義一樣,數組也必須先定義,後使用。典型的數組定義如下。
type name [elements]
類型 名稱[元素個數]
where type is a valid type (such as int, float...), name is a valid identifier and the elements field (which is always enclosed in square brackets []), specifies the length of the array in terms of the number of elements.上面的類型,必須是有效的數據類型(如整型,浮點數……),名稱也必須為合法的標識符,元素個數外面包含一個中括號,指定了數組的長度。
Therefore, the foo array, with five elements of type int, can be declared as,因此,有5個變量的foo整型數組,可以這樣定義:
int foo[5];
NOTE: The elements field within square brackets [], representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.數組元素個數即中括號包起來,表示這個數組元素包含的個數,必須是一個常量表達式。數組是內存中靜態的一個區段,在編繹階段(程序運行之前)需要確定它的長度。
Initializing arrays 數組初始化By default, regular arrays of local scope (for example, those declared within a function) are left uninitialized. This means that none of its elements are set to any particular value; their contents are undetermined at the point the array is declared.默認情況下,數組一般不會給定元素具體值。也就是說各個元素的值不確定,數組定義時,內容未知。
But the elements in an array can be explicitly initialized to specific values when it is declared, by enclosing those initial values in braces {}. For example。也可以在數組定義時,顯性的初始化具體的值,可以用大括號包起來,如下所示:
int foo [5] = { 16, 2, 77, 40, 12071 };
This statement declares an array that can be represented like this:
我們可以用下面的圖例來表示數量存儲情況:
The number of values between braces {} shall not be greater than the number of elements in the array. For example, in the example above, foo was declared having 5 elements (as specified by the number enclosed in square brackets, []), and the braces {} contained exactly 5 values, one for each element. If declared with less, the remaining elements are set to their default values (which for fundamental types, means they are filled with zeroes). For example:大括號中的值的個數應該不大於數組定義的個數(如下圖所示,編繹錯誤Too many initializers for int[5])。上面的例子中有5個元素的數組foo,大括號裡有5個整數,如果小於5個也是可以的。
int bar [5] = { 10, 20, 30 };
初始化3個元素,2個為0
Will create an array like this:
The initializer can even have no values, just the braces:
也可以不給定具體的值,留空。
int bar [5] = { };
This creates an array of five int values, each initialized with a value of zero:
這樣的話會創建5個整型元素,初始化為0。
When an initialization of values is provided for an array, C++ allows the possibility of leaving the square brackets empty []. In this case, the compiler will assume automatically a size for the array that matches the number of values included between the braces {}:
當然也可以把數量元素的地方留空,那麼下面的定義在編繹時,數組的長度與大括號中的元素個數一致。
int foo [] = { 16, 2, 77, 40, 12071 }
After this declaration, array foo would be 5 int long, since we have provided 5 initialization values.定義後,數組有5個整數值,因為我們給定5個數。
Finally, the evolution of C++ has led to the adoption of universal initialization also for arrays. Therefore, there is no longer need for the equal sign between the declaration and the initializer. Both these statements are equivalent。C++的後續版本也支持沒有等於號的初始化,下面兩個數組初始化是等價的。
int foo[] = { 10, 20, 30 };
int foo[] { 10, 20, 30 };
Static arrays, and those declared directly in a namespace (outside any function), are always initialized. If no explicit initializer is specified, all the elements are default-initialized (with zeroes, for fundamental types).
靜態數組(指定義在函數外面),總是被初始化的,如沒有給定特定的值,則給定默認的值(如基本數值類型,給定0值)
Accessing the values of an array 數組元素的存取The values of any of the elements in an array can be accessed just like the value of a regular variable of the same type. The syntax is:
數組元素的值,可以如下面的例子中進行存取:
name[index] 數組名稱[索引]
name[index]
Following the previous examples in which foo had 5 elements and each of those elements was of type int, the name which can be used to refer to each element is the following,上面的例子中foo數組有5個元素,每個元素的類型相同均為整數類型,每個元素的存取,可能通過名字加索引號,如下:
For example, the following statement stores the value 75 in the third element of foo:下面的例子是把第3個元素的值賦值75(存操作)
foo [2] = 75;
and, for example, the following copies the value of the third element of foo to a variable called x:下面的例子,把foo的第3個元素的值給變量x(取操作)
x = foo[2]
Therefore, the expression foo[2] is itself a variable of type int.foo[2]本身相當於一個變量類型為整型。
Notice that the third element of foo is specified foo[2], since the first one is foo[0], the second one is foo[1], and therefore, the third one is foo[2]. By this same reason, its last element is foo[4]. Therefore, if we write foo[5], we would be accessing the sixth element of foo, and therefore actually exceeding the size of the array.大家注意索引的編號,foo[0],foo[1],……foo[5]分別是1號到5號,而foo[6]是越界的,這個特別小心。
In C++, it is syntactically correct to exceed the valid range of indices for an array. This can create problems, since accessing out-of-range elements do not cause errors on compilation, but can cause errors on runtime. The reason for this being allowed will be seen in a later chapter when pointers are introduced.在C++中越界錯誤在編繹時不會報錯,但是在運行階段會產生嚴重錯誤,這個我們在後面的指針會重點介紹的。
At this point, it is important to be able to clearly distinguish between the two uses that brackets [] have related to arrays. They perform two different tasks: one is to specify the size of arrays when they are declared; and the second one is to specify indices for concrete array elements when they are accessed. Do not confuse these two possible uses of brackets [] with arrays.
兩個地方使用中括號,請注意了:一個是定義數組,一個是引用數組的元素。
int foo[5];// declaration of a new array
foo[2] = 75;// access to an element of the array.
The main difference is that the declaration is preceded by the type of the elements, while the access is not.定義時,數組前面會有一個類型說明,而使用數組元素沒有。
Some other valid operations with arrays:下面是有效的數量元素的操作。
foo[0] = a;
foo[a] = 75;
b = foo [a+2];
foo[foo[a]] = foo[2] + 5;
For example:
// arrays example
#include <iostream>
using namespace std;
int foo [] = {16, 2, 77, 40, 12071};
int n, result=0;
int main ()
{
for ( n=0 ; n<5 ; ++n )
{
result += foo[n];
}
cout << result;
return 0;
}
//結果為:12206
Multidimensional arrays 多維數組Multidimensional arrays can be described as "arrays of arrays". For example, a bidimensional array can be imagined as a two-dimensional table made of elements, all of them of a same uniform data type.
多維數組,可以描述為數組中的數組。二維數組可以認為是二維表格構成,裡面裝載數據,所有數據的類型相同。
jimmy represents a bidimensional array of 3 per 5 elements of type int. The C++ syntax for this is:jimmy 表示一張二維數量,3行5列的數據。語法如下圖:
int jimmy[3][5];
and, for example, the way to reference the second element vertically and fourth horizontally in an expression would be:
第2行,第4列的元素你可以這樣表示:
int jimmy[1][3];
remember that array indices always begin with zero.注意每行每列下標是0打頭的。
Multidimensional arrays are not limited to two indices (i.e., two dimensions). They can contain as many indices as needed. Although be careful: the amount of memory needed for an array increases exponentially with each dimension. For example:多維數組不限於二維,它們可以包含多個分量,要注意的是隨著維度的增加,內存的存儲空間也是指數級的增加的。
char century [100][365][24][60][60];
declares an array with an element of type char for each second in a century. This amounts to more than 3 billion char! So this declaration would consume more than 3 gigabytes of memory!如上面案例,定義字符類型的數組(年,日,時,分和秒)這個數組的數量是30億個字符,所以它會使用3G內存。
At the end, multidimensional arrays are just an abstraction for programmers, since the same results can be achieved with a simple array, by multiplying its indices:多維數組對於程式設計師來說實際上是一種數學的抽象,它可以用低維數組來表示(降維),乘以它的一維的長度即可。
1
2
intjimmy [3][5];// is equivalent to
intjimmy [15];// (3 * 5 = 15)
With the only difference that with multidimensional arrays, the compiler automatically remembers the depth of each imaginary dimension. The following two pieces of code produce the exact same result, but one uses a bidimensional array while the other uses a simple array:
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0; n<HEIGHT; n++)
for (m=0; m<WIDTH; m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
}
None of the two code snippets above produce any output on the screen, but both assign values to the memory block called jimmy in the following way:
Note that the code uses defined constants for the width and height, instead of using directly their numerical values. This gives the code a better readability, and allows changes in the code to be made easily in one place.
Arrays as parameters 數組作為參數At some point, we may need to pass an array to a function as a parameter. In C++, it is not possible to pass the entire block of memory represented by an array to a function directly as an argument. But what can be passed instead is its address. In practice, this has almost the same effect, and it is a much faster and more efficient operation.有時,我們需要把數組作為參數傳遞給函數。在C++中,把整個內存空間作為一個整體傳遞給函數做為參數,不太可行。所以傳遞的是一個數組的地址。在實際效果來看實際是一樣的,便後者更快,更有效。
To accept an array as parameter for a function, the parameters can be declared as the array type, but with empty brackets, omitting the actual size of the array. For example:作為一個函數的數組參數,參數定義為數組類型,中括號裡面為空,忽略數組的長度。void procedure (int arg[])
This function accepts a parameter of type "array of int" called arg. In order to pass to this function an array declared as:函數接受整型數組名為arg,作為一個實際內存的存在體,數組定義如下:
int myarray [40];
it would be enough to write a call like this:
procedure (myarray)
cestd;
Here you have a complete example:
下面是完整的程序
// arrays as parameters
#include <iostream>
usingnamespacestd;
void printarray (int arg[],int length) {
for(int n=0; n<length; ++n)
cout << arg[n] <<' ';
cout <<'\n';
}
intmain ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray (secondarray,5);
}
//輸出
//5 10 15
//2 4 6 8 10
In the code above, the first parameter (int arg[]) accepts any array whose elements are of type int, whatever its length. For that reason, we have included a second parameter that tells the function the length of each array that we pass to it as its first parameter. This allows the for loop that prints out the array to know the range to iterate in the array passed, without going out of range.上面的代碼中,第一人參數是整型數組及它的長度。第二個參數,告訴函數數組的長度,為了後面的For循環列印出遍歷數組的長度,不至于越界。
In a function declaration, it is also possible to include multidimensional arrays. The format for a tridimensional array parameter is:
當然也可以使用多維數組作為函數的參數。三維數組作為形參的格式如下。
base_type [] [depth][depth]
For example, a function with a multidimensional array as argument could be:
函數的實例如下:
void procedure(int myarray[][3][4])
Notice that the first brackets [] are left empty, while the following ones specify sizes for their respective dimensions. This is necessary in order for the compiler to be able to determine the depth of each additional dimension.
注意第一個中括號是留白的,而後面幾個給定了實際的長度,這是為了告訴編繹器確定其化維度的長度。
In a way, passing an array as argument always loses a dimension. The reason behind is that, for historical reasons, arrays cannot be directly copied, and thus what is really passed is a pointer. This is a common source of errors for novice programmers. Although a clear understanding of pointers, explained in a coming chapter, helps a lot.
在函數調用中,常常會少維度,原因是:由於歷史原因,數組不能直接拷貝,只能通過指針來傳遞,這個對初學者來說,經常容易犯錯。關於指針內容,我們會在後面的章節中再介紹。