C ++通过引用传递静态数组和动态数组

时间:2015-02-26 04:44:26

标签: c++ arrays pointers reference pass-by-reference

为了完全理解指针,值和引用是如何工作的,我正在制作一个基本的C ++程序,试图篡改一些静态和动态数组,并准确理解它们应该如何传入。

首先,我生成一个包含3个元素的静态数组。然后我将它传递给一个修改所有元素的函数。然后我将它传递给另一个具有略微不同签名的函数,但也可以改变数组的值。

接下来,我生成一个动态大小的数组,通过引用将其传递给函数,以便可以更改此动态大小的数组中的所有值。

代码如下:

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

void changeIndexStaticArrayMethod1(int* stat);
void changeIndexStaticArrayMethod2(int (&stat)[3]);
void changeIndexDynamicArrayMethod1(int* dyn, int size);

int main() {
    const int MAX = 3;
    int arr[MAX] = { 1,2,3 };

    changeIndexStaticArrayMethod1(arr);
    cout << arr[0] << endl;
    cout << arr[1] << endl;
    cout << arr[2] << endl;
    cout << endl;
    changeIndexStaticArrayMethod2(arr);
    cout << arr[0] << endl;
    cout << arr[1] << endl;
    cout << arr[2] << endl;

    int SIZE;
    cout << "Please choose a size for the array" << endl;
    cin >> SIZE;

    int *ne = new int[SIZE];
    //Build array
    for (int i = 0; i < SIZE; i++) {
        ne[i] = i;
    }

    changeIndexDynamicArrayMethod1(ne, SIZE);
    for (int i = 0; i < SIZE; i++) {
        cout << "ne[" << i << "] = " << ne[i] << endl;
    }


    //To hang program
    cin >> SIZE;

    delete[] arr;
    delete[] ne;
    return 0;
}

void changeIndexStaticArrayMethod1(int* stat) {
    stat[0] = 10;
    stat[1] = 20;
    stat[2] = 30;
}

void changeIndexStaticArrayMethod2(int (&stat)[3]) {
    stat[0] = 40;
    stat[1] = 50;
    stat[2] = 60;
}

void changeIndexDynamicArrayMethod1(int* dyn, int size) {
    for (int i = 0; i < size; i++) {
        dyn[i] = i * 10;
    }
}

以上所有代码都是我想要的,我只是有几个问题(为什么(通过引用传递数组的一些方法,我在其他SO问题上找到)。

  • 在changeIndexStaticArrayMethod1()和changeIndexDynamicArrayMethod1()函数中,为什么我们可以使用取消引用*运算符作为参考?我的膝跳反应是看到实际上通过值传递数组,因为它是取消引用运算符。我知道对于数组,它与使用变量有很大不同,但是,为什么以下内容对单个int变量不起作用:

    void changeStaticNumber(int * num){     num = 100; }

显然,如果我们使用&num而不是int* num,上面的内容将会起作用,显然我并不完全理解指针和数组之间的关系,但是当我们传递一个数组时,我无法弄清楚为什么通过引用,int* staticArray没问题。

对我遇到的这些问题的任何解释都将不胜感激。感谢。

3 个答案:

答案 0 :(得分:0)

让我看看我是否可以捅这个。

指针只是地址持有者。一旦你做int * ptr = myarray; ---你正在做的是将指针的地址存储到ptr中---数组名实际上是指向数组中第一个内存位置的指针。您可以使用指针算法来获取其他所有内容,例如myarray +1将指向下一个位置或myarray [1]。

当您需要修改数组时,按值传递并不是很有用。通过引用传入实际上是指向数组并传递它的指针。由于像向量这样的数组是连续的内存块,因此您可以非常轻松地索引它们。

就你的例子而言,void changeStaticNumber(int * num){num = 100;因为你试图做的是将100存储到指针的地址中,所以无法工作。如果您使用deference num并使其为void changeStaticNumber(int * num){* num = 100;它会工作,因为你实际上更进一步,并访问num指向的数据。当你使用&amp; num时它基本上是同一个东西 - &amp;只是给你一些东西的地址。

例如,如果要将指向int的指针指向

int num = 5; int *ptr = &num;

此时ptr在num中具有相同的地址。要打印出num或ptr指向的数据,你需要取消引用或更进一步,因为我喜欢告诉自己并取消引用cout << *ptr;

答案 1 :(得分:0)

changeIndexStaticArrayMethod1changeIndexDynamicArrayMethod1中,您没有传递数组,没有通过引用传递(仅当参数类型是引用类型时才会发生 - 即使用&) 。该参数的类型为int *(指向int的指针)。您正在通过值传递指向int 的指针。两种功能中都没有“解引用运算符”。

ne已经是int *,所以传递它并不是什么特别的事。 arrint [3],是一个数组,而不是指针。在C中,当一个数组 - T用于需要指向 - T的上下文时,它被隐式转换(不需要你做任何事情)到指向它的第一个指针元件。因此,当您执行changeIndexStaticArrayMethod1(arr)时,编译器会获取指向arr的第一个元素的指针,并将其传递给函数。

[]运算符用于指针。 a[i]始终保证与*(a + i)相同。在changeIndexStaticArrayMethod1changeIndexDynamicArrayMethod1函数中,[]用于使用指向第一个元素的指针访问后续元素。

答案 2 :(得分:0)

  

为什么我们能够使用dereference *运算符作为参考?

C中的*意味着很多东西。它可以表示一元间接(“内容”)运算符,它可以表示二进制乘法运算符,它可以表示指针声明。 int* stat是一个指针声明。

由于你没有使用*取消引用该函数内指针的内容,我不太清楚你在问什么。

当您在main()中获取数组的数组名称时,它会“衰减”为指向第一个元素的指针。那么这些函数的作用是按值获取指针。如果通过键入*stat = something;取消引用指针,则可以访问main中的实际数组。

如果您做一些奇怪的事情,例如更改指针本身,例如stat++;,那么它不会影响main中使用的地址。您通过值传递指针本身,因此指针是本地副本。

  

我的膝跳反应是看到实际上通过值传递数组,因为它是解除引用运算符。

你不能真正按C或C ++中的值传递数组,而不需要使用脏技巧(将它们存储在结构或类中)。例如,如果您的函数被编写为void changeIndexStaticArrayMethod1(int stat[3]),它仍会为您提供指向第一个元素的指针。它不会按值传递数组,因为语法可能会诱使您相信。

  

为什么以下内容不能用于单个int变量:

void changeStaticNumber(int* num){ num = 100; }

因为num是指针本身,而不是其内容。为了编写这样的代码,您可以通过引用int& num传递变量。在这些行的后面,这与传递指针非常相似,只是简化了语法。

要更好地理解指针和数组之间的关系,首先阅读整章:http://c-faq.com/aryptr/index.html(C和C ++在指针方面完全相同)。