我不明白函数在作为参数传递时如何更改指针的状态。例如,在此代码中 -
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void inc(int* a) {
a++;
}
void change(int* a) {
a[0] = 2;
a[1] = 3;
}
int main() {
int* a = (int*) malloc(2 * sizeof(int));
a[0] = 1;
a[1] = 2;
printf("%d \n",*a);
inc(a);
printf("%d \n",*a);
change(a);
return 0;
}
当我尝试使用函数inc()
时,观察到指针不会递增。
但与此同时,change()
实际上确实改变了指针的值。
你能解释为什么inc()
不起作用吗?
答案 0 :(得分:1)
这是画一些照片的好地方。当你写
int* a = (int*) malloc(2 * sizeof(int));
你得到一个如下所示的设置:
+---------+ +---------+---------+
| addr X | ---> | ????? | ????? |
+---------+ +---------+---------+
pointer a
in main
将值分配给a[0]
和a[1]
后,事情如下所示:
+---------+ +---------+---------+
| addr X | ---> | 1 | 2 |
+---------+ +---------+---------+
pointer a
in main
现在,我们假设您致电inc(a)
。这会将指针a
的副本传递给inc
函数。由于指针是唯一被复制的东西,所以现在看起来像这样:
+---------+ +---------+---------+
| addr X | ---> | 1 | 2 |
+---------+ +---------+---------+
pointer a ^
in main |
|
+---------+ |
| addr X |-----------+
+---------+
pointer a
in inc
请注意,现在有两个名为a
的指针,但它们并不是同一个指针。如果你有两个叫Zoe的朋友 - 他们有相同的名字,但他们不是同一个人。
在inc
内,你写了
a++;
表示&#34;使指针a
前进,指向当前指向的int
下的+---------+ +---------+---------+
| addr X | ---> | 1 | 2 |
+---------+ +---------+---------+
pointer a ^
in main |
|
+---------+ |
| addr Y |---------------------+
+---------+
pointer a
in inc
。&#34;这看起来像这样:
a
请注意main
中a
的回复未更改,因为我们正在操作inc
的副本。再回想一下Zoe的比喻 - 如果你和一个叫Zoe的人谈话,那并不意味着你和另一个叫Zoe的人交谈过。因此,当a
返回时,+---------+ +---------+---------+
| addr X | ---> | 1 | 2 |
+---------+ +---------+---------+
pointer a
in main
的副本会消失在以太网中,我们就会离开:
inc
由于指针未更改,因此您在调用change
之前和之后会看到相同的值。
但是调用change
的方式不同。当您最初拨打+---------+ +---------+---------+
| addr X | ---> | 1 | 2 |
+---------+ +---------+---------+
pointer a ^
in main |
|
+---------+ |
| addr X |-----------+
+---------+
pointer a
in change
时,情况如下:
a[0] = 2;
当你现在写
a
您正在说&#34;按照名为2
的指针,查看您最终的位置,并将值+---------+ +---------+---------+
| addr X | ---> | 2 | 2 |
+---------+ +---------+---------+
pointer a ^
in main |
|
+---------+ |
| addr X |-----------+
+---------+
pointer a
in change
放在那里。这意味着我们看到以下内容:
a[1] = 3
编写a
也意味着&#34;按照名为1
的指针,转到您找到的索引3
处的元素,并将其替换为+---------+ +---------+---------+
| addr X | ---> | 2 | 3 |
+---------+ +---------+---------+
pointer a ^
in main |
|
+---------+ |
| addr X |-----------+
+---------+
pointer a
in change
。这给出了以下内容:
change
现在,在main
返回后,我们又回到a
。 main
中的+---------+ +---------+---------+
| addr X | ---> | 2 | 3 |
+---------+ +---------+---------+
pointer a
in main
指针未发生变化 - 它仍然在寻找与之前相同的位置 - 但它所指向的数组的值已更改
Invalid author specified. Example: A U Thor <author@example.com>
总结:
答案 1 :(得分:1)
inc
更改传递给它的指针的值 - 但传递给它的是原始指针值的副本,因此原始的仍然存在不变。
change
不会改变指针本身,它会改变指针所指向的内容。
如果您希望inc
更改原始指针,您必须将其更改为返回递增指针的函数,然后您将指定给原始指针:< / p>
int* inc(int* ip) {
return ++ip;
}
然后在main
:
a = inc(a);
或者您可以重写inc
以将指针指针作为参数,然后将原始指针的地址传递给它,如:
void inc(int** ipp) {
*ipp = *ipp + 1;
}
然后从main
将其称为:
inc(&a);
祝你好运。
答案 2 :(得分:0)
void inc(int* a) {
a++;
此处a
按值传递,因此在a
内更改inc()
不会反映在外部。
void change(int* a) {
a[0] = 2;
a[1] = 3;
此处a
也按值传递,但您可以使用a
更改a
指向的内容a[0]
和a[1]
答案 3 :(得分:0)
a++
会增加局部变量a
的值。也就是说,踩到内存中的下一个位置。如果你想增加它,你应该使用(*a)++
符号a[1]
只是隐藏指针算术的语法糖。这真正意味着*(a + 1)。这有一个有趣的副作用。 a[1]
与1[a]
答案 4 :(得分:0)
对于inc
函数,它正在更改参数a
的值。由于C中的所有函数参数都是按值传递的,因此此更改不会反映在调用函数中。
调用change
时,会执行以下操作:
a[0] = 2;
a[1] = 3;
与此相同:
*(a + 0) = 2;
*(a + 1) = 3;
具体来说,指针a
正在解除引用。该函数不会更改a
,而是a
指向的内容。这就是为什么变化在函数之外可见。
答案 5 :(得分:0)
inc
void inc(int* a) {
a++;
}
更改指针值的副本,不会影响传递的参数。要影响参数,请通过引用而不是值传递它:
void inc(int*& a) {
a++;
}