所以我只是有一个简单的问题,我原本认为代码一般从上到下执行。所以下面我在C中附加了一个使用指针的示例,并且只是想让某人向我解释为什么打印* p1时的输出是12我原来的思维过程是它会打印25。谢谢
int a = 10, *p1, *p2;
p1 = &a;
*p1 = 25;
p2 = p1;
*p2 = 12;
printf("%d", *p1);
答案 0 :(得分:7)
让我们分解一下:
int a = 10, *p1, *p2; // nothing special
p1 = &a; // p1 now holds the address of a. printf("%d", *p1) would print 10, as it is the current value of a.
// in this point, printf("%d-%d", *p1,a); would print 10-10 (printf("%d",*p2); is UB as p2 is uninitialized)
*p1 = 25; // remember that p1 = &a, meaning that now a = 25. Basically you changed (the variable) a, using a pointer instead of changing it directly.
p2 = p1; // p2 now holds the value of p1, meaning it too points to a
// in this point, printf("%d-%d-%d", *p1,*p2,a); would print 25-25-25
*p2 = 12; // *p2 = 12, and so does *p1, and so does a
// in this point, printf("%d-%d-%d", *p1,*p2,a); would print 12-12-12
printf("%d", *p1);
您应该记住,a
是int
,其中包含整数值,而p1,p2
是int *
,其中包含int
的地址。在p1 = &a
之后,对a
的每次更改都意味着*p1
也会发生变化,因为*p1
实际上是*(&a)
[} ... < / EM> a
]。在p2 = p1
之后,同样适用于p2
。
我原本以为代码一般从上到下执行。
嗯,确实如此:)
答案 1 :(得分:5)
此处使用的地址值完全是任意的,例如
int a = 10, *p1, *p2;
前一行声明了一个int
类型的变量(a
)和指向int
的两个指针(p1
和p2
)
内存
address | memory | variable
1050 | 10 | a
1054 | xxx | p1
1058 | xxx | p2
p1 = &a; // &a is address of a, ie here, 1050
上一行后的内存
address | memory | variable
1050 | 10 | a
1054 | 1050 | p1
1058 | xxx | p2
p1
商店&#34; 1050&#34 ;; *p1
,即存储在p1
内存储的地址的值为10 *p1 = 25; // *p1 means value stored at address stored inside p1
上一行后的内存
address | memory | variable
1050 | 25 | a
1054 | 1050 | p1
1058 | xxx | p2
p1
商店&#34; 1050&#34 ;; *p1
,即存储在p1
内的地址的值,现在为25 p2 = p1;
上一行后的内存
address | memory | variable
1050 | 25 | a
1054 | 1050 | p1
1058 | 1050 | p2
p1
商店&#34; 1050&#34 ;; *p1
,即存储在p1
内存储的地址的值为25 p1
中p2
内存储的值;所以p2
指向a
,即存储地址&#34; 1050&#34; *p2 = 12;
上一行后的内存
address | memory | variable
1050 | 12 | a
1054 | 1050 | p1
1058 | 1050 | p2
printf("%d", *p1); // Print value stored at address stored inside p1
我们在这里可以看到:
p1
和p2
是指针:它们存储变量的地址&
(与&a
中一样):返回变量的地址*
(如int *p1
中所示):声明指向变量的指针(此处为int
变量)*
(如*p1 = 25
中所示):访问存储在指针中存储的地址的值您可以看到不同的地址和值:
printf("address of a: %p\n", &a);
printf("address of p1: %p\n", &p1);
printf("address of p2: %p\n", &p2);
// address stored inside p1 (ie value stored inside p1)
printf("address stored inside p1: %p\n", p1);
// address stored inside p2 (ie value stored inside p2)
printf("address stored inside p2: %p\n", p2);
printf("value of a: %d\n", a);
printf("value pointed by p1: %d\n", *p1);
printf("value pointed by p2: %d\n", *p2);
答案 2 :(得分:4)
输出为12,因为p1
和p2
指向相同的内存位置(变量a
),因此当您将12分配给*p2
时,它会更改值a
的{{1}},p1
也恰好指向。
我希望这会有所帮助。
答案 3 :(得分:2)
因为p1
和p2
都是指针,所以你这样做:
p2 = p1;
这意味着p2
指向与p1
相同的位置,反之亦然。你随后这样做:
*p2 = 12;
这会将*p2
设置为12,但由于p1
指向与p2
相同的位置,*p1
现在也将等于12;
当指针指向相同的东西时,您已经创建了别名。您可以通过两个不同的名称访问相同的数据。
答案 4 :(得分:0)
*p1 = 25;
如果您现在打印*p1
,那么您将获得25。
p2 = p1;
现在p2指向p1的相同的位置。
*p2 = 12;
现在你在p2指向的整数中写入12,这是p1指向的相同的,与前面的p2 = p1
赋值一样。
因此,您修改了p1指向的整数值。这解释了为什么打印*p1
现在给你12:
printf("%d", *p1)