[英]confusion in passing a pointer to function in C
我试图理解 C 中的指针并编写了这段代码
#include <stdio.h>
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
printf("%d\n",*pa);
printf("%d\n",*pb);
printf("%d\n",a);
printf("%d",b);
}
现在输出(如预期)是
7
5
7
5
我对正在发生的事情有一点了解,但我有一个困惑
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
这是正在发生的事情吗
或者是 fa 和 fb 首先影响 pa 和 pb,依次影响 a 和 b。
- 在我调用交换函数之后,就会发生这种情况
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
如果您的意思是在进入swap
之后,那么是。 那是正确的。 参数作为副本传递,这意味着在函数fa
和fb
内部从调用者那里获取pa
和pb
的副本。
- 我们交换 fa 和 fb 的值,然后交换 a 和 b 的值,因为 pa 和 pb 指向 a 和 b,它们也指向这些新值。
号fa
和fb
根本没有接触。 它们被取消引用。 这意味着,它们指向的地址会受到影响。 您可以使用printf
打印这些指针变量的内容。 他们不会改变。 而是更改了a
和b
的内容。
顺便说一句:你的printf
语句没有多大意义。 您应该在函数调用之前和之后打印以查看任何效果。
对于初学者,请注意您的返回类型为int
函数swap
返回任何内容。
int swap(int *fa,int *fb){
返回类型int
没有意义。
该函数可以声明为
void swap(int *fa,int *fb);
函数 swap 不交换其参数的值。
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
它交换参数对象所指向的对象,因为在函数中使用了取消引用指针的表达式,例如
*fa
或*fb
。
这是一个演示程序,它表明指针fa
和fb
的值没有改变。
#include <stdio.h>
void swap(int *fa,int *fb){
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
}
int main(void)
{
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
return 0;
}
程序输出可能看起来像
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
正如所见,指针在函数的开头和结尾具有相同的值。 交换的是指向对象的值。
并且指针fa
和fb
不影响 main 中声明的指针pa
和pb
。 因为作为函数局部变量的指针fa
和fb
获得了存储在指针pa
和pb
中的值的副本。
当您将指针传递给您的函数时,您传递了一个包含地址的变量。 当您取消引用 fa(或 fb)时,您将获得该地址的实际值。 所以当你修改它时,你修改了两个指针的值,因为它们指向同一个地址。
为了更好地理解指针,您可以使用实际的假地址。 假设变量“a”存储在 RAM 中的地址 0x9000,变量“b”存储在地址 0x10000。
#include <stdio.h>
int swap(int *fa,int *fb){ //fa and fb are variables of type pointer which contain 0x9000 and 0x10000 respectively
int temp = *fa; //temp contains the content of address 0x9000 (a)
*fa = *fb; //address 0x9000 contains content of address 0x10000 (b)
*fb = temp; //address 0x10000 contains content of temp (a)
}
int main(){
int a=5,b=7;
int* pa = &a; //pa is a variable of type pointer which contains 0x9000
int* pb = &b; //pb is a variable of type pointer which contains 0x10000
swap(pa,pb);
}
不要忘记 int* 是一个指向 int 的指针类型的变量。 这意味着该变量包含一个 int 类型变量的地址。 实际上它只是指向内存。 你可以写类似的东西
int* a = 0x9000;
您将有一个 int 类型的指针指向地址 0x9000。 这将是有效的语法,但您的操作系统会抱怨您无权访问该地址。 如果你写
long* a = 0x9000;
唯一的区别是取消引用时获得的字节数。 当您取消引用一个指针时,您将获得该类型包含的字节数。 对于 int* 类型,当您取消引用时,您将获得从地址 0x9000 开始的 4 个字节(32 位)。 使用 long* 类型,您将获得从地址 0x9000 开始的 8 个字节(64 位)。
int* 或 long* 类型变量的大小是相同的,因为这仅取决于 CPU 的架构。 因此,使用这两种方法,您将获得一个大小相同的指针类型变量。 唯一的区别是取消引用时获得的字节数。
我们交换 fa 和 fb 的值,然后交换 a 和 b 的值,因为 pa 和 pb 指向 a 和 b,它们现在指向这些新值。
不 - 你交换fa
和fb
指向的值,分别是a
和b
。 fa
和fb
的值(以及pa
和pb
)永远不会改变。
我修改了你的代码如下:
#include <stdio.h>
#include <stdlib.h>
void swap(int *fa,int *fb){
printf( "Entering swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "Leaving swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
printf( "Before swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
swap(pa,pb);
printf( "After swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
return EXIT_SUCCESS;
}
运行时,它给出输出1 :
Before swap: a = 5, b = 7, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 5, *pb = 7
Entering swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 5, *fb = 7
Leaving swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 7, *fb = 5
After swap: a = 7, b = 5, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 7, *pb = 5
所以,我们可以看到以下都是正确的:
fa == pa == &a
*fa == *pa == a == 5 // before swap, 7 after swap
fb == pb == &b
*fb == *pb == b == 7 // before swap, 5 after swap
fa
和pa
以及&a
都是相同的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.