我想澄清一些关于指针的内容,因为我觉得这在C ++中很难实现。当我声明一个指针并将其传递给像:
这样的函数时//just an example
void showInt(int* numbers)
{
numbers += 3;
}
int main()
{
int* a = 10;
showInt(a);
return 0;
}
当我将变量a
传递给函数时,我实际上是将原始变量传递给它吗?或者它是创建变量的副本,然后将其传递给函数?
如何通知副本或真实/原始副本?
答案 0 :(得分:3)
你做不到
int* a = 10
没用,编译器会告诉你错误。
执行此操作时:
//just an example
void showInt(int* numbers)
{
numbers += 3;
}
int main()
{
int a = 10;
showInt(&a);
return 0;
}
您通过了 a 的地址,然后将 3 添加到此地址,因此没有任何更改。
如果你改变:
numbers += 3;
到
*numbers += 3;
然后你将修改变量 a 的值。
还有一种方法可以做到这一点: 只是改变
void showInt(int* numbers)
到
void showInt(int& numbers)
那么你可以使用
showInt(a);
并且您将修改 a 的值,并且不会创建副本。
答案 1 :(得分:0)
a
指向指针,指向值10
。如果要将值10
传递给方法,请使用*a
。就目前而言,您将内存位置传递给top方法。在该方法中,您将其递增3。
本身没有“复制”和“原始”:在main()
中,10
存在于内存中,a
拥有指向它的指针。在另一个方法[没有名字?]它需要一个int
- 而不是一个指针 - 所以如果你修改它你不是改变指针的目标,只是参数(它的作用就像一个局部变量)
希望在某种程度上有所帮助。
[编辑:您现在已更改了使用int*
参数而不是int
的top方法。这更有意义..让我修改我的答案]
首先我要澄清一下,在你的代码中没有复制任何对象(实际上代码中根本没有真正的对象,只是内存中的int和传递的指针并且可能被修改)。
showInt
现在正确地使用指针。它会递增该指针,在这种情况下将其指向未定义/无效的内容。如果你做numbers += 3
那么数字只会指向它最初指针的3个字节,这就是所有改变的。这只是在该方法的范围内。
如果您执行了:*numbers += 3
,那么您将增加指针的目标,这意味着将10
替换为13
。无论在何处访问该内存,即main
。
我是否可以建议您阅读一下指针vs 引用的好处(例如int&
) - 有一篇不错的文章你应该有一个相当不错的'aha'时刻:)< / p>
答案 2 :(得分: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;
}
此函数将在第一个cout中打印值10,在下一个cout中打印50,因为在函数中更改了指向和引用的对象的值。 valfunc更改b副本的值,因此不会更改原始值。
答案 3 :(得分: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
所做的所有更改仅保留在此函数内;传递给此函数的原始变量的值将保持不变!但请注意以下内容:您无法更改传递给函数的指针(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
的地址通过变量showInt
传递给numbers
,现在函数可以写入该地址(现在是int对象的有效地址 - {{1}因此修改a
的值。当函数返回时,a
的值为13.请注意a
的地址在此处的任何时间点都不会更改。