C++數組詳解

2021-03-02 大學計算機基礎

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.

在函數調用中,常常會少維度,原因是:由於歷史原因,數組不能直接拷貝,只能通過指針來傳遞,這個對初學者來說,經常容易犯錯。關於指針內容,我們會在後面的章節中再介紹。

相關焦點

  • 在C++中將string轉換為char數組
    >輸出 : char s[] = { 'l', 'i', 'n', 'u', 'x', 'm', 'i' } ;輸入 : string s = "python" ;輸出 : char s[] = { 'p', 'y', 't', 'h', 'o', 'n' } ;一種方法是將string的內容複製到char數組
  • C++ vector詳解
    (給CPP開發者加星標,提升C/C++技能)https://www.cnblogs.com/ishen/p/12508379.html【導讀】:vector是一個封裝了動態大小數組的順序容器
  • C++ initializer_list 詳解
    用於表示某種特定類型的值的數組,和vector一樣,initializer_list也是一種模板類型。有了initializer_list之後,對於STL的container的初始化就方便多了,比如以前初始化一個vector需要這樣:std::vector v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);而現在c++
  • JavaScript數組 - 引用詳解
    基本數據類型詳解在學習數組引用詳解前,我們先來看基本數據類型的詳解舉個小例子:我們聲明一個a = 10;然後聲明一個函數,這個函數裡面有個參數為a把這個參數的a改成5,a = 5; 並且再加上alert(a);函數外我們先去alert(a);再調用這個函數把a寫在裡面傳進去
  • 小開帶你學C++|Lesson 8 do-while,二維數組和循環嵌套
    先來看do-while循環的寫法:int c=1,a=10;do{ c++;a--;}while(a>=0);很顯然,do裡的內容就是符合while條件的時候的內容。唯一的區別是,while循環是先判斷條件符不符合,然後在執行命令。而do-while則是先執行命令,如果符合條件就繼續執行,不符合就不再執行。
  • python+C、C++混合編程的應用
    有的語言專注於簡單高效,比如python,內建的list,dict結構比c/c++易用太多,但同樣為了安全、易用,語言也犧牲了部分性能。在有些領域,比如通信,性能很關鍵,但並不意味這個領域的coder只能苦苦掙扎於c/c++的陷阱中,比如可以使用多種語言混合編程。
  • C/C++編程筆記:數組和字符串丨多維數組詳解
    數組基礎在C / C ++中,我們可以用簡單的單詞將多維數組定義為數組數組。多維數組中的數據以表格形式(以行主要順序)存儲。
  • C++、java 和 C 的區別
    一、基礎類型c++:** java:** C#:1.以java為準,c++裡面的int short long 像這樣的整型 一般都有unsigned 和signed的區分 ,這個跟java和c# 的區別比較大,但c#裡面有unit ulong ushort 這三種就相當於c++的修飾詞unsigned,當c++李明的變量類型定義unsigned,就默認是整數。
  • c語言指針與字符數組
    ,並且數組大小要大於或等於大括號中的元素個數,數組在內存中是連續存儲的,它的內存分布c是這個數組的名稱,數組元素在內存中的分布,第一個h的地址是100,每個元素佔1個字節,整個數組的內存地址分布就如上圖所示。
  • json for modern c++的使用
    json for modern c++是一款非常好用的json庫,具有語法直觀和使用簡單的特點,並且是用C++11標準編寫的,此外還支持STL和json容器之間的轉換,可謂集方便又強大。本文推薦給廣大C++程式設計師,相信學習完本文之後,在處理json時一定會得心應手。
  • C++實現對數組的下標排序例子
    本文實現的功能是:ip轉換為數值, 數值轉換為ip,具體代碼如下: 在C++中,怎樣實現對數組的下標排序呢?stdio.h>#include <stdlib.h>#include <time.h>#define size 10struct temp{ int number; int index;};int main(){ int s[size]; //通過隨機數得到數組的初始值
  • C 語言會比 C++ 快?
    該算法基本上只使用堆分配的數組作為數據結構,並使用原始指針。該算法需要一個自定義實現的哈希表和一個排序例程。我們的代碼中不需要 resize 或 push_back,所有數組都使用正確的大小進行初始化。我們的要求足夠低,我們這種 std::vector 的替代方式僅僅需要 40行代碼 [5],並且主要由 operator[] 定義組成。
  • 「最佳實踐」C++陷阱與套路
    理解at()和operator[]的區別 :at()會做下標越界檢查,operator[]提供數組索引級的訪問,在release版本下不會檢查下標,VC會在Debug版本會檢查;c++標準規定:operator[]不提供下標安全性檢查。5. C++標準規定了std::vector的底層用數組實現,認清這一點並利用這一點。
  • NumPy中對數組進行切分及一些基本概念
    數組切分上面講了使用棧操作把多個數組組裝到一起的方法。接下來看一下它的逆操作:把一個數組分為及部分。在NumPy中,該操作要用到切分方法。同理,我們也有一組函數,水平切分用hsplit( )函數,垂直切分用vsplit( )函數。
  • 一文帶你了解c++和c中字符串的使用
    說完了c,那麼對於我們的c++來說,它定義字符串就簡單多了,因為有關鍵字來定義,你一看就知道。那麼下面大家就隨著我的筆步一起來看看究竟吧!有可能有些網友還沒怎麼接觸到c++(c++它是一門面向對象的語言,而c是一門面向過程的語言,所以這裡可能沒接觸過那個面向對象的網友不習慣這個用法,不過還是建議至少要掌握一門面向對象的語言,在這個發展快速的時代,不能太固步自封了(我這裡也是簡單的介紹一下c++中的字符串,不會設計到類和對象什麼的,只是和c語言做個對比)。)1、什麼是字符串?
  • c++ fstream + string處理大數據
    (4)上面兩點算是自己的誤解吧,因為c++裡面也有也有與之對應的fstream類,c++map容器類,詳見c++map簡介(5)c++裡面也有相對比較成熟的string類,裡面的函數也大部分很靈活,沒有的也可以很容易的實現split,strim等,詳見c++string實現(6)最近從網上,看到了一句很經典的話,c++的風fstream類+string
  • 詳解:Python 取numpy數組的某幾行某幾列方法(含對與錯示例)
    詳解:Python 取numpy數組的某幾行某幾列方法(含對與錯示例) 今天為大家帶來的內容是Python 取numpy數組的某幾行某幾列方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,要是喜歡的話記得點讚轉發收藏不迷路哦!!!
  • C++ 的門門道道 | 技術頭條 - CSDN
    因為效率,C++被設計為系統級的程式語言,效率是優先考慮的方向,c++秉持的一個設計哲學是不為不必要的操作付出任何額外的代價,所以它有別於java,不給成員變量和局部變量做默認初始化,如果需要賦初值,那就由程式設計師自己去保證。
  • C++之字符串類學習總結
    一、回顧c語言對字符串的實現:一般我們在c語言要實現對字符串操作的話,一般是採用字符數組或者一組函數來實現的,為啥這樣做呢,那是因為c語言裡面根本就沒有字符串類型的關鍵字;而且c語言也支持自定義類型,所以更加無法獲得字符串類型為了解決這個問題,在c++中,引入了自定義類型,而且可以通過類來完成對字符串類型的定義。
  • C++的字符輸入輸出流和字符數組的拼接
    3:字符數組的拼接,C++預處理器的一個重要功能就是可以進行字符數組的拼接。如果如果兩個或多個用加了引號的字符數組相鄰,並且它們中間沒有任何其他標點符號,編譯器就會把這些字符數組連接成單個字符數組。cin >> number;cout << "value in octal = 0" << oct << number << endl;cout << "value in hex = 0x" << hex << number << endl;//字符數組的拼接演示