指針變量的幾個常見問題

一、指針變量的初始化問題

指針變量同普通變量一樣,使用之前不僅要定義說明,而且必須進行初始化,指針的初始值必須是一個地址,決不允許賦予任何其他數據,通常是一個數據的地址或地址變量或空指針。

void main()
{
    int i,*p;
    i=100;
    *p=i;
    printf("*p=%d\n",*p);
}

編譯時會出現警告:warning C4700: 使用了未初始化的局部變量“p”。

程序中定義了一個指針變量 *p,但沒有對其進行初始化,將該指針變量稱爲“野指針”。如果此後對該指針變量所指的存儲空間進行操作,程序會出現嚴重的錯誤。因爲在定義指針變量後,指針變量的值是不確定的,即指針隨機指向某個內存地址,此時的指針所指的內存直接賦值操作,將該單元中原有的數據覆蓋,使該數據丟失,若指針指向的是系統的數據區中,會導致系統運行的異常甚至死機。因此,C編程時要及時把指針變量賦值,使指針有正確的指向。

上面程序可修改爲:

void main()
{
    int i,*p;
    i=100;
    p=&i;
    printf("*p=%d\n",*p);
}

程序編譯成功。

二、指針賦值帶來的內存“丟失”問題

在C語言中,指針之間是可以相互賦值的,但是使用不當可能會造成部分內存的“丟失” ,即這部分內存空間不能再被該任何程序訪問。如:   
#include<stdio.h>
#include<stdlib.h>

void main()
{
    float  *a,*b;
    a=(float*)malloc( sizeof( float));
    b=(float*)malloc( sizeof( float));
    *a=float(227.5);
    *b=float(163.9);
    a=b;
    printf("%f,%f",*a,*b);
}

上例中,將指針變量 b 賦給了指針變量 a,使 a 與 b 都指向分配給b的內存空間,而原先分配給a的內存空間未釋放,不能再被其它任何程序訪問,該內存空間成了“無效內存塊”,內存空間“丟失”了。在大型軟件系統中如果出現含類似程序段的函數,而該函數又反覆被調用,將可能導致內存空間無故溢出。 解決方法:在將一個指針變量賦給另一個指針變量之前,應先用 free( ) 函數釋放所佔有的內存空間,以使這部分空間可以由系統重新支配,即應在賦值語句前執行:free (a)。

三、指針變量作爲函數參數

指針變量作爲函數的參數,是將一個變量的地址傳送到另一個函數中。如,

void swap(int *p1,int *p2)

{

   int temp;

   temp=*p1;

   *p1=*p2;

   *p2=temp;

   printf("*p1=%d,*p2=%d\n",*p1,*p2);

}

void main()

{

   int a,b;

   int *pointer_1,*pointer_2;

   scanf("%d,%d",&a,&b);

   pointer_1=&a;pointer_2=&b;

   if(a<b)

      swap(pointer_1,pointer_2);

   printf("a=%d,b=%d\n",a,b);

   printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);

}

運行情況:

5,9  <——(輸入5,9)

*p1=9,*p2=5

a=9,b=5

*pointer_1=9,*pointer_2=5

 

程序說明:

swap 是用戶定義的函數,它的作用是交換兩個變量(a 和 b)的值。swap 函數的形參 p1、p2 是指針變量。程序運行時,先執行main函數,輸入 a 和 b 的值。然後將 a 和 b 的地址分別賦給指針變量 pointer_1 和 pointer_2,使 pointer_1 指向 a,pointer_2 指向 b。接着執行 if 語句,由於 a〈b,因此執行 swap 函數。注意實參 pointer_1 和 pointer_2 是指針變量,在函數調用時,將實參變量的值傳遞給形參變量。採取的依然是“值傳遞”方式。因此虛實結合後形參 p1 的值爲&a,p2 的值爲&b。這時  p1 和 pointer_1 指向變量 a,p2 和 pointer_2 指向變量 b。接着執行執行 swap 函數的函數體使 *p1 和*p2 的值互換,也就是使 a 和 b 的值互換。函數調用結束後,p1 和 p2不復存在(已釋放)。最後在main函數中輸出的 a 和 b 的值是已經過交換的值。

請注意,不能企圖通過改變形參指針的值(指向)而使實參指針的值改變。如,

#include<stdio.h>

void swap(int *p1,int *p2)

{

   int *p;

   p=p1;

   p1=p2;

   p2=p;

   printf("*p1=%d,*p2=%d\n",*p1,*p2);

}

void main()

{

   int a,b;

   int *pointer_1,*pointer_2;

   scanf("%d,%d",&a,&b);

   pointer_1=&a;pointer_2=&b;

   if(a<b)

      swap(pointer_1,pointer_2);

   printf("a=%d,b=%d\n",a,b);

   printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2);

}

運行情況:

5,9  <——(輸入5,9)

*p1=9,*p2=5

a=5,b=9

*pointer_1=5,*pointer_2=9

C 語言中實參變量和形參變量之間的數據傳遞是單向的“值傳遞”方式。指針變量作爲函數參數也要遵循這一規則。調用函數可以改變實參指針變量所指向變量的值,但不能改變實參指針變量的值(指向)。

總結:要通過函數調用得到 n 個要改變的值,可以:(1)在主調函數中設 n 個變量,用 n 個指針變量指向它們;(2)然後將指針變量作爲實參,將 n 個變量的地址傳給所調用的函數的形參;(3)通過形參指針變量,改變該 n 個變量的值(而不是改變形參指針變量的指向);(4)主調函數中就可以使用這些改變了值的變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章