C++中关于使用函数处理数组

(1)define pointer types

有的时候, 使用typedef用于定义一个type name or definition的alias 很有用。

首先是的程序易读性很好。

举个例子:

typedef double Kilometers;
Kilometers distance;


对于指针的时候, 我们使用typedef 创建一个pointer type names 的 alias, 好处也是很多的。 主要有两个advantages.

(1) avoid the mistake of omiting an asterisk。 例如, 当我们想要声明两个指针的时候, 很容易犯如下错误。

int* p1, p2;
正确的做法是:

int *p1, *p2;

为了避免上述错误的发生, 我们可以如下做:

typedef int* IntPtr;

IntPtr p1, p2;

(2) 第二个advantage 是当我们想要define a function with a call by reference  parameter for  a pointer variable, without the defined pointer type name, you need to include both an * and an & in the declaration for the function. and the details may be confusing,   so use the follow code.

void sampleFunction(IntPtr& pointerVariable);


易错点: pointer as call by value parameters.

EX:

#include 

using namespace std;

typedef int* IntPointer;

void sneaky(IntPointer temp); // pointer as call by value parameters

int main() {
    IntPointer p;

    p = new int;
    *p = 77;
    cout << "Before call to function *p == "
         << *p << endl;

    sneaky(p);
    cout << "After call to function *p == "
         << *p << endl;

    delete p;
    return 0;
}
void sneaky(IntPointer temp) {
    *temp = 99;

    cout << "Inside function call *temp == "
         << *temp << endl;
}

运行结果为:

C++中关于使用函数处理数组_第1张图片


对于上例子中, 参数temp 是一个call by value 的参数, 所以他是一个Local variable。 当sneak 函数被调用的时候, temp 变量的值被设定为指针变量p的值。 由于temp 是一个Local variable, 所以生存期不会出了函数, 调用结束后, tamp变量会消失掉, 如果我们在函数内部修改可temp的内容, 也不会改变p 的值。 因为是call by value 的嘛。


但是, p 指向的地址的内容却可能随着temp的改变而改变, 如上例的有77变成了99..虽然变量p 本身的内容没有改变, 还是只想那个地址。


这里有一个易错点, 就是当我们的class 或者struct 里面有一个member variable 为一个pointer type的时候, 如果我们在一个函数中使用call by value arguments of this class type, 函数中对复制进来的对象做出改动的时候, 会implicitly 改变到指针指向的值, 也就是修改到了外部的物件的指针指向的内容, 这是我们不希望发生的。 所以只要class 里面有指针变量, 当我们要将这个类作为函数的参数的时候, 我们需要定义一个copy constructor。



动态数组学习。

下面对于使用的数组时正确的:

#include 

using namespace std;



typedef int* IntPtr;

int main() {
    int a[10];

    IntPtr p;
    p = a;//okay
    cout << sizeof(a) << endl;
    cout << sizeof(p) << endl;
    return 0;
}

运行结果为:

C++中关于使用函数处理数组_第2张图片

当我们执行p = a; 语句的时候,于是p 和 a 指向内存中同一块区域。 所以 p[0], p[1], p[3], ... p[9]分别可以代表 a[0], ..., a[10].。 也就是说, 只要指针p 指向的是一个数组的内存区域, 我们就可以使用the square bracket notation(当然也可以使用*(p+i)代表 array[i]).

另外, 虽然上例子中a 表示数组名, 不难看出其还有内存大小的(是内存大小, 而非数组长度的信息)的信息, 因为sizeof(a) 的大小是40啊。

a 存储的是a[0]的地址, 即数组的起始地址。我们有的时候可以将数组名看成一个指针变量, 但是必须吃保留态度, 因为你无法修改一个数组变量的地址。 例如下例就是非法的:

a = p2;// you cannot assign a different address to a 
上述语句非法的原因就是Array variable is not of type int*, 我们可以进一步修饰, 将其看成一个呗const 修饰的指针变量, (当然数组之间的直接赋值也是错误的)。 但是任然有保留, 因为数组变量a 还附带有数组size 的 information。 


创建动态数组。


使用指针和new创建一个动态数组。

typedef double* DoublePtr;
DoublePtr p;
p = new double[10];

注意动态分配数组的时候, 关于分配数组的大小, 可以在程序run的时候配置。

注意delete和new 配套使用, delete [] 和 new [] 配套使用。 关于动态分配, 更多参见absolute C++。

下面说说一个函数如何返回一个数组(A function returns an array)
在C++中, an array type is not allowed as the return type of a function. 例如下面的语句非法:

int [] someFunction();//illegal

我们的解决办法是返回指向数组的指针, 如下是合法的。

int* someFunction;//legal
如下例:
#include 

using namespace std;

int* doubler(int a[], int length);
//Postcondition: length is the size of the array a
//all indexed variables of a have values
//returns: a pointer to an array of the same size as a in which
// each indexed variable is double the corresponding element

int* doubler2(int a[], int length);//原位修改, 不许动态分配了

int main() {
    int a[] = {1, 2, 3, 4, 5};
    int* b;
    int length = sizeof(a) / sizeof(int); // 5

    b = doubler(a, length);

    int i;
    cout << "Array a: \n";
    for(i = 0; i < length; i++) {
        cout << a[i] << " ";
    }
    cout << endl;

    cout << "Array b: \n";
    for(i = 0; i < length; i++) {
        cout << b[i] << " ";
    }
    cout << endl;

    delete[] b;
    return 0;

}

int* doubler(int a[], int length) {
    int* temp = new int[length];  // 当然此时必须动态分配的才能保存到函数体外

    for(int i = 0; i < length; i++) {
        temp[i] = 2 * a[i];
    }
    return temp;
}

int* doubler2(int a[], int length) {
   // 当然此时必须动态分配的才能保存到函数体外

    for(int i = 0; i < length; i++) {
        a[i] = 2 * a[i];
    }
    return a;
}
运行结果:

C++中关于使用函数处理数组_第3张图片


关于多维数组的分配和释放, 参见absoluteC++。


返回一个数组的另一个办法。

C++中关于使用函数处理数组_第4张图片

C++中关于使用函数处理数组_第5张图片 C++中关于使用函数处理数组_第6张图片


你可能感兴趣的:(综合,C++)