1. 程式人生 > >C語言中指標傳遞問題

C語言中指標傳遞問題

要求:通過呼叫函式實現兩個值的交換

例如:輸入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;

這裡寫圖片描述