C語言中指標傳遞問題
阿新 • • 發佈:2019-02-02
要求:通過呼叫函式實現兩個值的交換
例如:輸入5,9 —– 輸出9,5
不能到達預期的結果的程式碼
#include<stdio.h>
void main()
{
void swap(int *p1, int *p2);
int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1 = &a;
pointer_2 = &b;
printf("指標pointer_1、pointer_2初始化的地址(自身) %d %d\n", &pointer_1, &pointer_2); //1703732 1703728
printf("指標pointer_1、pointer_2儲存的值 %d %d\n", pointer_1, pointer_2); //1703740 1703736
printf("\n");
printf("a,b交換之前的地址 %d %d\n", &a, &b); //1703740 1703736
printf("a,b交換之前的值 %d %d\n", a, b); //5 9
if (a < b)
{
swap(pointer_1,pointer_2);
}
printf("指標pointer_1、pointer_2初始化的地址(自身) %d %d\n", &pointer_1, &pointer_2); //1703732 1703728
printf("指標pointer_1、pointer_2儲存的值 %d %d\n", pointer_1, pointer_2); //1703740 1703736
printf("\n");
printf("a,b交換之後的地址 %d %d\n", &a, &b); //1703740 1703736
printf("a,b交換之後的值 %d %d\n", a, b); //5 9
}
void swap(int *p1,int *p2)
{
printf("\n******************呼叫函式開始****************");
printf("\n");
printf("before_self %d %d\n",&p1,&p2); //1703644 1703648
printf("before_storage_address %d %d\n",p1,p2); //1703740 1703736
printf("before_result %d %d\n",*p1,*p2); //5 9
int *p;
p = p1;
p1 = p2;
p2 = p;
printf("\n");
printf("after_self %d %d\n",&p1,&p2); //1703644 1703648
printf("before_storage_address %d %d\n",p1,p2); //1703736 1703740
printf("after_result %d %d\n",*p1,*p2); //9 5
printf("******************呼叫函式結束****************\n\n");
}
輸出結果
原因
在給a和b分別賦值5,9後,把a的地址1703740給了指標變數pointer_1,把b1703736的地址給了指標變數pointer_2(為了方便,地址用%d輸出,不同的PC,情況不同,但是原理都一樣)。然後呼叫函式,把指標儲存的值(a、b的地址)傳遞給P1、P2指標。
swap(pointer_1,pointer_2);
void swap(int *p1, int *p2);
在呼叫函式的進行交換的程式碼,可以看出,只是單純的將各自儲存的地址進行交換而已。
int *p;
p = p1;
p1 = p2;
p2 = p;
所以,指標變數只是在呼叫函式裡交換了儲存的地址,可以在呼叫函式裡輸出9,5。但是一旦呼叫結束,P1、P2指標變數就會被釋放。並沒有在根本上進行交換。
能到達預期的結果的程式碼
只需要將呼叫函式修改如下:
void swap(int *p1,int *p2)
{
printf("\n******************呼叫函式開始****************");
printf("\n");
printf("before_self %d %d\n",&p1,&p2); //1703644 1703648
printf("before_storage_address %d %d\n",p1,p2); //1703740 1703736
printf("before_result %d %d\n",*p1,*p2); //5 9
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
printf("\n");
printf("after_self %d %d\n",&p1,&p2); //1703644 1703648
printf("before_storage_address %d %d\n",p1,p2); //1703740 1703736
printf("after_result %d %d\n",*p1,*p2); //9 5
printf("******************呼叫函式結束****************\n\n");
}
輸出結果
原因
修改後的呼叫函式的指標變數,交換的不再是地址,而是通過地址找到a、b的值,將a、b的值進行交換。
int p;
p = *p1;
*p1 = *p2;
*p2 = p;