Array of Strings in C++
在C++中有3中方法可以建立Array of Strings
- 使用二維數組(C/C++)
1.1 用字元數組表示的字元串
字元數組的初始化有兩種
char str2[6]="china"; char str3[5] = {'c','h','i','n','a'};
第一種初始化方式必須要為'\0'配置設定空間,也就是說, 用一個字元串初始化字元數組時,字元數組除了要儲存這個字元串以外,還必須要儲存至少一個'\0',
第二個初始化方式是用每一個單獨的字元去初始化字元數組,在這種情況下不需要儲存'\0', 隻要滿足字元數組的空間>=所要配置設定的字元大小即可。
注意:字元數組的指派不能用一個字元串指派,而隻能使用單個字元去對數組元素一一指派。
在C語言中還可以用字元指針指向字元串:
char *str1="china";
str指向的是大小為5位元組的記憶體空間,在這個空間中沒有'\0',這個空間的首位址儲存在str1中。
不同于字元數組,對字元指針可以使用字元串整體指派:
str1 = ”I love China";
1.2 用二維數組表示多個字元串char color[][10] = {"blue","Red","orange","yellow"};
char color[][10] = {"blue","Red","orange","yellow"};//sizeof(color) = 40
for(int i = 0; i < 4;i++) cout<<color[i]<<endl;
//由于C/C++的多元數組是行優先,是以color數組的元素分布如下:
b l u e \0 \0 \0 \0 \0 \0 R e d \0 \0 \0 \0 \0 \0 \0 o r a n g e \0 \0 \0 \0 y e l l o w \0 \0 \0 \0 color[i]就是第i行的字元串的首位址。
輸出是
這種方法的缺點:
- Number of Strings and Size of String – both the values are fixed.
- A 2D array is allocated, whose second dimension is equal to maximum sized string which causes wastage of space.
- 使用string(C++)
#include<bits/stdc++.h>
using namespace std;
int main()
{
// Initialize String Array
string colour[4] = {"Blue", "Red", "Orange", "Yellow"};
// Print Strings
for (int i = 0; i < 4; i++)
cout << colour[i] << "\n";
}
這種方法的缺點:
Array is of fixed Size
- 使用vectors(C++) STL Container Vector can be used to dynamically allocate Array.
從以上3點來看,vector應該是c++中建立字元串數組最好的方法了// C++ program to demonstrate vector of strings using #include<bits/stdc++.h> using namespace std; int main() { // Declaring Vector of String type vector <string> colour; // Initialize vector with strings using push_back // command colour.push_back("Blue"); colour.push_back("Red"); colour.push_back("Orange"); colour.push_back("Yellow"); // Print Strings stored in Vector for (int i=0; i<colour.size(); i++) cout << colour[i] << "\n"; }
注意:‘\0'在C語言中是 字元串結束符,是以隻有數組在處理字元串時才會用多餘的一個位元組來儲存它,在其他情況(非字元數組)下,數組不會儲存它
Array Decay in C++
What is Array Decay?
數組退化是指數組丢失了數組元素的類型和數組的大小。這通常發生在向函數按值傳遞或傳遞指針參數時,結果就是僅僅把實參的首位址傳給了形參的數組,這時數組就退化為一個指針,數組的大小也會變成指針的大小而不是原數組的大小。
舉個簡單的例子:
輸出#include <iostream> using namespace std; void findSize(int arr[]) { cout << sizeof(arr) << endl; } int main() { int a[10]; cout << sizeof(a) << " "; findSize(a); return 0; }
d40 8
輸出// C++ code to demonstrate array decay #include<iostream> using namespace std; // Driver function to show Array decay // Passing array by value void aDecay(int *p) { // Printing size of pointer cout << "Modified size of array is by " " passing by value: "; cout << sizeof(p) << endl; } // Function to show that array decay happens // even if we use pointer void pDecay(int (*p)[7]) { // Printing size of array cout << "Modified size of array by " "passing by pointer: "; cout << sizeof(p) << endl; } int main() { int a[7] = {1, 2, 3, 4, 5, 6, 7,}; // Printing original size of array cout << "Actual size of array is: "; cout << sizeof(a) <<endl; // Calling function by value aDecay(a); // Calling function by pointer pDecay(&a); return 0; }
Actual size of array is: 28 Modified size of array by passing by value: 8 Modified size of array by passing by pointer: 8
How to prevent Array Decay?
一個典型的解決辦法就是把數組大小也作為一個參數傳給函數,并且對數組參數不要用sizeof。
另外一個解決辦法就是把數組按引用傳遞給函數,這樣就避免了數組轉化為指針,也就避免了退化。比如
其它知識點:// C++ code to demonstrate prevention of // decay of array #include<iostream> using namespace std; // A function that prevents Array decay // by passing array by reference void fun(int (&p)[7]) { // Printing size of array cout << "Modified size of array by " "passing by reference: "; cout << sizeof(p) << endl; } int main() { int a[7] = {1, 2, 3, 4, 5, 6, 7,}; // Printing original size of array cout << "Actual size of array is: "; cout << sizeof(a) <<endl; // Calling function by reference fun(a); return 0; }
- 數組指針:int (*t)[N] 表示一個數組指針,它的意思是,t是一個指向 在記憶體中連續存儲的 N個int資料所組成的 塊的指針,N必須與實參二維數組的列值相同。先看小括号得知t是一個指針,往右看得知它指向的是數組,再看最左邊,數組元素是int型的。(所有的指針都可以這麼解讀,包括函數指針)
- 指針數組 :int (*t)[N] 表示t是一個數組,其中的元素是int*類型。
- 數組引用:int (&t)[N] 表示t是一個數組的引用,其它的意義同數組指針,可以作為其它數組的呃别名。
How to find size of array in C/C++ without using sizeof ?
舉例:
// C++ program to find size of an array by using a
// pointer hack.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "
<< size;
return 0;
}
在解釋原理之前,先說明 arr與&arr的差別
如果分别列印arr和&arr的值,你會發現這兩者的值是一樣的:
printf("array=%p : &array=%p\n", array, &array);
printf("array+1 = %p : &array + 1 = %p", array+1, &array+1);
然而将它們分别加1以後的值就不一樣了,這是因為 arr與&arr雖然都指向相同的位址,但是位址的類型是不同的。
- arr指向的是數組内的第一個元素的首位址,該元素類型是int,是以arr+1相當于第一個元素的首位址加4
- &arr指向的是整個數組的首位址,類型是數組,是以&arr+1就相當于數組的首位址加數組的大小(機關是byte,本例是24=0x18)
原理:
&arr ==> Pointer to an array of 6 elements.
[See this for difference between &arr
and arr]
(&arr + 1) ==> Address of 6 integers ahead as
pointer type is pointer to array
of 6 integers.
*(&arr + 1) ==> Same address as (&arr + 1), but
type of pointer is "int *".類型轉化
*(&arr + 1) - arr ==> Since *(&arr + 1) points
to the address 6 integers
ahead of arr, the difference
between two is 6. 利用指針減法