指针混淆:c中的swap方法
Pointer Confusion: swap method in c
#include<stdio.h>
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
/*int *p=b;
b=a;
a=p;
*/
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
swap(&a,&b);
printf("%d %d",a,b);
}
上面是代码。
如果我将 3 5 作为输入,那么它应该交换它的值,并且 5 3 应该作为输出出现。
我通过尝试 int p=*b thing
得到了答案
但是我也试过注释部分,但是没有用。
所以,我检查了他们在 swap 和 main 中的地址。
交换 int *a 和 int *b 它们的地址改变了
然而,当我回到main时,a和b的地址并没有改变...
所以一开始我想:是不是在main里面没有改,因为参数int *a,int *b是局部变量?
但我还了解到,当指针和参数用作参数时,它们的值可能会发生变化,这与其他变量不同...
我真的很奇怪为什么第二种方法(注释部分)没有交换值...
在第二种方法中,您使用的局部变量被限制在函数的范围内swap
。因此,main 函数中的变量 a
或 b
与 swap
函数中定义为参数的变量 a
或 b
不同。
当你使用指针时,swap
函数会改变指针指向的值(即函数改变a
和[=12地址处的值=] 在 main
函数中声明)。
假设你的意思是
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
该代码只是交换 swap()
函数中 指针 的值。这不会在 main()
中交换地址,因为正如您所说,"parameter int *a,int *b is local variable".
当你像这样调用函数swap()
时
swap(&a,&b);
a
和b
的地址被传递,成为swap()
函数中的局部变量。您无法更改 a
或 b
的地址 - 它们在内存中有一个位置。
在有效的代码中
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
}
您不更改指针的值,而是更改指针指向的内存中的值,这就是它起作用的原因。
虽然 C 是按值传递的,但如果您将某物的地址作为值传递给函数 可以 修改其范围之外的东西,因为您告诉函数该变量在哪里是。
在 C 中,函数中声明的所有变量都是该特定函数的局部变量。
所以,你在函数 swap
中写了一些东西
int *p=b;
上面的代码要做的是,它将b的值复制到p中。所以,当函数swapreturn时,它的局部变量p,b,a就会消失
如果您想在函数中更改原始对象,您必须通过引用将它们传递给函数。
在 C 中,通过引用传递对象意味着通过指向原始对象的指针间接传递对象。
否则,如果您将原始对象本身传递给函数,函数将处理对象的副本。很明显,改变副本不会影响原始对象。
这正是这个函数中发生的事情
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
该函数处理传递给该函数的指针的副本作为此调用中的参数
swap(&a,&b);
这就是函数确实交换了声明为其参数的两个指针的值。但它们不是传递给函数的原始指针。它们是指针的副本。所以原始指针的值没有改变
函数交换一般可以看下面的方式
void swap( T *a, T *b )
{
T tmp = *a;
*a = *b;
*b = tmp;
}
其中 T
是相同的类型说明符。
所以如果你想交换 int
类型的对象,那么在上面的函数中 T
将是 int
并且函数看起来像
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
如果你想交换 int *
类型的指针的值,那么 T
将是 int *
并且函数看起来像
void swap( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
这是一个演示程序。
#include <stdio.h>
void swap1( int *pa, int *pb )
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void swap2( int **ppa, int **ppb )
{
int *tmp = *ppa;
*ppa = *ppb;
*ppb = tmp;
}
int main(void)
{
int a = 3, b = 5;
swap1( &a, &b );
printf( "a = %d b = %d\n", a, b );
// reset again the values of the variables
a = 3; b = 5;
int *pa = &a, *pb = &b;
swap2( &pa, &pb );
printf( "*pa = %d *pb = %d\n", *pa, *pb );
return 0;
}
它的输出是
a = 5 b = 3
*pa = 5 *pb = 3
也就是一开始在程序中交换了两个int
类型的对象,所以想象中的类型说明符T
就是int
.
然后交换指向对象 a
和 b
的两个指针。所以想象中的类型说明符 T
int *
.
交换指针后,指针 pa
现在指向对象 b
,指针 pb
现在指向对象 a
。
#include<stdio.h>
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
/*int *p=b;
b=a;
a=p;
*/
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
swap(&a,&b);
printf("%d %d",a,b);
}
上面是代码。
如果我将 3 5 作为输入,那么它应该交换它的值,并且 5 3 应该作为输出出现。 我通过尝试 int p=*b thing
得到了答案但是我也试过注释部分,但是没有用。
所以,我检查了他们在 swap 和 main 中的地址。
交换 int *a 和 int *b 它们的地址改变了
然而,当我回到main时,a和b的地址并没有改变...
所以一开始我想:是不是在main里面没有改,因为参数int *a,int *b是局部变量?
但我还了解到,当指针和参数用作参数时,它们的值可能会发生变化,这与其他变量不同...
我真的很奇怪为什么第二种方法(注释部分)没有交换值...
在第二种方法中,您使用的局部变量被限制在函数的范围内swap
。因此,main 函数中的变量 a
或 b
与 swap
函数中定义为参数的变量 a
或 b
不同。
当你使用指针时,swap
函数会改变指针指向的值(即函数改变a
和[=12地址处的值=] 在 main
函数中声明)。
假设你的意思是
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
该代码只是交换 swap()
函数中 指针 的值。这不会在 main()
中交换地址,因为正如您所说,"parameter int *a,int *b is local variable".
当你像这样调用函数swap()
时
swap(&a,&b);
a
和b
的地址被传递,成为swap()
函数中的局部变量。您无法更改 a
或 b
的地址 - 它们在内存中有一个位置。
在有效的代码中
void swap(int *a,int *b){
int p=*b;
*b=*a;
*a=p;
}
您不更改指针的值,而是更改指针指向的内存中的值,这就是它起作用的原因。
虽然 C 是按值传递的,但如果您将某物的地址作为值传递给函数 可以 修改其范围之外的东西,因为您告诉函数该变量在哪里是。
在 C 中,函数中声明的所有变量都是该特定函数的局部变量。 所以,你在函数 swap
中写了一些东西int *p=b;
上面的代码要做的是,它将b的值复制到p中。所以,当函数swapreturn时,它的局部变量p,b,a就会消失
如果您想在函数中更改原始对象,您必须通过引用将它们传递给函数。
在 C 中,通过引用传递对象意味着通过指向原始对象的指针间接传递对象。
否则,如果您将原始对象本身传递给函数,函数将处理对象的副本。很明显,改变副本不会影响原始对象。
这正是这个函数中发生的事情
void swap(int *a,int *b){
int *p=b;
b=a;
a=p;
}
该函数处理传递给该函数的指针的副本作为此调用中的参数
swap(&a,&b);
这就是函数确实交换了声明为其参数的两个指针的值。但它们不是传递给函数的原始指针。它们是指针的副本。所以原始指针的值没有改变
函数交换一般可以看下面的方式
void swap( T *a, T *b )
{
T tmp = *a;
*a = *b;
*b = tmp;
}
其中 T
是相同的类型说明符。
所以如果你想交换 int
类型的对象,那么在上面的函数中 T
将是 int
并且函数看起来像
void swap( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
如果你想交换 int *
类型的指针的值,那么 T
将是 int *
并且函数看起来像
void swap( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
这是一个演示程序。
#include <stdio.h>
void swap1( int *pa, int *pb )
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
void swap2( int **ppa, int **ppb )
{
int *tmp = *ppa;
*ppa = *ppb;
*ppb = tmp;
}
int main(void)
{
int a = 3, b = 5;
swap1( &a, &b );
printf( "a = %d b = %d\n", a, b );
// reset again the values of the variables
a = 3; b = 5;
int *pa = &a, *pb = &b;
swap2( &pa, &pb );
printf( "*pa = %d *pb = %d\n", *pa, *pb );
return 0;
}
它的输出是
a = 5 b = 3
*pa = 5 *pb = 3
也就是一开始在程序中交换了两个int
类型的对象,所以想象中的类型说明符T
就是int
.
然后交换指向对象 a
和 b
的两个指针。所以想象中的类型说明符 T
int *
.
交换指针后,指针 pa
现在指向对象 b
,指针 pb
现在指向对象 a
。