数组(array)应用

来源:互联网 发布:红蜘蛛软件破解网络 编辑:程序博客网 时间:2024/06/03 13:54

Array of Strings in C++

在C++中有3中方法可以创建Array of Strings

  1. 使用二维数组(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";
char color[][10] = {"blue","Red","orange","yellow"};

1.2 用二维数组表示多个字符串


char color[][10] = {"blue","Red","orange","yellow"};//sizeof(color) = 40
for(int i = 0; i < 4;i++)    cout<<color[i]<<endl;


//由于C/C++的多维数组是行优先,所以color数组的元素分布如下:
blue\0\0\0\0\0\0Red\0\0\0\0\0\0\0orange\0\0\0\0yellow\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.

  1. 使用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

  1. 使用vectors(C++) STL Container Vector can be used to dynamically allocate Array.
    // 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";    }

    从以上3点来看,vector应该是c++中创建字符串数组最好的方法了

注意:‘\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;}
输出

40 8
d

// C++ code to demonstrate array decay#include<iostream>using namespace std; // Driver function to show Array decay// Passing array by valuevoid 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 pointervoid 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: 28Modified size of array by passing by value: 8Modified 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 referencevoid 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. 利用指针减法