2011-11-06 139 views
0

我想澄清关于指针的一些问题,因为这是我认为在C++中很难的东西。当我宣布一个指针,并把它传递给像一个函数:原始对象的C++指针和复制对象的指针

//just an example 
void showInt(int* numbers) 
{ 
    numbers += 3; 
} 

int main() 
{ 
    int* a = 10; 
    showInt(a); 

    return 0; 
} 

当我传递变量a的功能,我在实际传递的原始变量呢?还是创建一个变量的副本,然后将其传递给函数?

我如何知道我是否通过了一份副本或真实/原始副本?

+0

您需要该函数的名称。 –

+1

@TommyA是的,对不起,我注意到并编辑了它:P – Danny

+5

无论你怎么想'int * a = 10;'都行,不这样做。 –

回答

3

你不能这样做

int* a = 10 

这是没有意义的,你的编译器会告诉你错误。

当你这样做:

//just an example 
void showInt(int* numbers) 
{ 
    numbers += 3; 
} 

int main() 
{ 
    int a = 10; 
    showInt(&a); 

    return 0; 
} 

有你传递的一个的ADRESS,然后添加这个ADRESS,所以没有什么变化。

如果更改:

numbers += 3; 

*numbers += 3; 

,那么你就修改变量一个的价值。

还有一种方法来做到这一点: 只是改变

void showInt(int* numbers) 

void showInt(int& numbers) 

,那么你可以使用

showInt(a); 

,你会修改值一个,并且复制将不会被创建。

0

a指的是指针,指向的值为10。如果要将值10传递给方法,请使用*a。就目前而言,您将内存位置传递给顶层方法。在这种方法中,你通过3

增加它有没有“复制”和“原始”本身:在main(),该10存在于内存中,并a具有指向它。在另一个方法中[没有名字?]它需要一个int - 不是一个指针 - 所以如果你修改它,你不会改变指针的目标,只是参数(它像一个局部变量)。

希望能以某种方式提供帮助。

[编辑:你已经改变了现在采用int*参数代替int的第一种方法。这更有意义..让我修改我的答案]

首先,我想澄清一下,代码中没有复制对象(实际上代码中根本没有实际的对象,只是内存中的一个int和一个指针通过并可能修改)。

showInt现在需要一个指针,正确。它会增加那个指针,在这种情况下指向一个未定义/无效的东西。如果你做numbers += 3那么数字就会指向它最初指向的地方的3个字节,这一切都改变了。这只在该方法的范围内。

如果你这样做:*numbers += 3那么你会增加指针的目标,这意味着用13代替10。无论访问什么内存,即在main中,都会生效。

我可以建议你做一些阅读到指针的好处VS 引用(如int&) - 一个体面的文章,你应该有一个相当不错的“啊哈”的时刻:)

+0

Ugh;我也错过了'int * a = 10;'创建一个指向地址10的指针,这是无效的。所以除了上面的内容,你可能的意思是'int v = 10; int * a =&v;' - 分配一个值为10('v')的int然后指向它('a')。 –

+0

“呃;我也错过了int * a = 10这一点;创建了一个指向地址10的指针,这是无效的。”并非真正无效,但我同意这可能不是他想要的。 –

+0

在某些嵌入式系统中,内存位置10可能指向一些IO寄存器或其他东西.. :) –

0

的指针你是传递指针的副本作为参数,指针指向原始变量。因此,如果您取消引用指针,您将拥有原始值。记住一个指针基本上是一个地址,int *是一个整数的地址,如果你改变了指针的值,你改变了地址,这意味着指针会指向别的东西,如果你改变了这个值指针指向的内容,您将在指向同一对象时更改该值。

void ptrfunc(int *a) 
{ 
    *a = 10; 
} 

void reffunc(int &a) 
{ 
    a = 50; 
} 

void valfunc(int a) 
{ 
    a = 30; 
} 

int main() 
{ 
    int b = 20; 
    // Pass the point to b to the function, will alter the original. 
    ptrfunc(&b); 
    cout << b << endl; 
    // Pass a reference to b to the function, will alter the original. 
    ptrfunc(b); 
    cout << b << endl; 
    // Pass the value of b to the function, will not alter the original. 
    valfunc(b); 
    cout << b << endl; 
    return 0; 
} 

该功能将打印值10 INT第一COUT,和50中,因为对象的值指出,和引用的下一个在功能被改变。valfunc更改b的副本的值,因此不会改变原始值。

0

让我们通过你的例子:

void showInt(int* numbers) // (1) 
{ 
    numbers += 3;   // (2) 
} 

int main() 
{ 
    int* a = 10;   // (3) 
    showInt(a);    // (4) 
    return 0; 
} 

(1)numbers变量传递给这个函数变量的副本; (2)因为(1)在numbers上所做的所有更改将仅保留在此函数内;因为(1)所有在numbers上作出的更改将仅保留在此函数内;传递给这个函数的原始变量的值将保持不变!但请注意以下几点:您不能更改传递给该函数的指针(a)的值,而是通过该指针的副本(即numbers),您可以更改它指向的值! 这是主要技巧 - 一旦你在函数内部有地址,你就可以在该地址写入,并且在函数返回后这些更改仍然保留。在地址写入包括指针解引用,但你幸运地没有这样做 - 我说'幸运',因为你传递的地址只是内存中的任意地址(10)。如果您试图在地址10处写信,您的程序可能会崩溃。 (3)你已经声明a是“指向int的指针”类型,所以它的值应该是某个int对象的地址。你在这里犯了一个危险的错误,因为你认为10是一个int的有效地址,但你实际上并不知道该地址是什么。

(4)您正在向函数传递变量a的副本。函数将其值存储在numbers变量中并增加它。所以numbers现在包含地址13(不是某个整数变量的值是13的地址!)。 a但仍然相同,它仍然具有相同的值,10

你可能想是这样的:

void showInt(int* numbers) 
{ 
    *numbers += 3;   // (1) 
} 

int main() 
{ 
    int a = 10;    // (2) 
    showInt(&a);    // (3) 
    return 0; 
} 

(1)功能,在保持numbers地址修改值。指针被取消引用。 (2)我们需要有一个int变量的有效地址,而不是随机选取的地址(如10)。因此我们声明int变量,a。它的地址是&a

(3)的地址a通过可变numbers传递给showInt和功能现在可以写入到该地址(这是现在int对象的一个​​有效地址 - a)等修改的a值。函数返回时,a的值为13.请注意,a的地址在此处的任何时间点都不会更改。