2014-01-28 90 views
-1

为什么会出现在结果的差时,我打电话的空隙函数内部的阵列,并且当我调用的空隙函数内标:差异结果

传递数组成void函数:

#include <iostream> 
const int n_cells = 1; 
using namespace std; 

void function1(int c[n_cells], int a, int b) 
{ 
    c[0] = a + b; 
} 

int main(){ 
    int a = 3; 
    int b = 4; 
    int c[n_cells]; 
    function1(c, a, b); 
    cout<<"c = "<<c[0]; 

    return 1; 
} 

结果:

C = 7

传递一个标量成void函数

#include <iostream> 

using namespace std; 

void function1(int c, int a, int b) 
{ 
    c = a + b; 
} 

int main(){ 
    int a = 3; 
    int b = 4; 
    int c; 
    function1(c, a, b); 
    cout<<"c = "<<c; 

    return 1; 
} 

结果:

C = 2130567168 //一些垃圾值

P.S.对于为什么我每次收到与上面给出的相同垃圾价值的任何评论?

+0

编译时打开警告。如果您使用的是GCC,请以“-Wmost”开头。一个好的编译器会警告你在第二个程序中'c'未初始化。 –

回答

3
void function1(int c[n_cells], int a, int b) 

有效地将指针传递给调用者的数组。然后function1在调用者的数组上运行,这意味着调用者可以使用任何更新。

void function1(int c, int a, int b) 

通过的c副本。它无法访问调用者的变量,因此无法更新它。 main从未分配过c因此您打印出未初始化的值。

如果要更新一个整数参数,您可以通过引用传递它,而不是

void function1(int& c, int a, int b) 
//    ^

,而不是传递呼叫者的c的副本,这个现在将指针传递给调用者的变量,允许function1到更新它。

1

数组参数实际上转换为类型int*,所以您实际上正在做的是将指针传递给在main中声明的数组的第一个元素。因此,当您分配给此数组的第一个元素时,您正在修改main中的数组。

但是,当您通过int时,将int复制到该函数中并修改该副本。此修改将不会在main中看到。

1

你可以得到同样的结果在第二个方案,如果当你传递一个数组的值是由编译器隐式转换为指向它第一个元素,你会定义功能通过以下方式

void function1(int *c, int a, int b) 
{ 
    c[0] = a + b; 
} 

。所以这些函数声明是等价的并且声明相同的函数

void function1(int c[n_cells], int a, int b); 
void function1(int c[10], int a, int b); 
void function1(int c[], int a, int b); 
void function1(int *c, int a, int b); 

将最后一个声明与我向第二个程序展示的声明进行比较。

在第二个程序中,该函数获取其参数的副本。它的参数是函数的局部变量。因此,在退出本地变量将被销毁的函数后,该局部变量的任何更改都将被丢弃。

在第一个程序中,该函数获取数组的第一个元素的地址。它在这个地址进行更改。所以原始数组的相应元素将会改变。