一、指針變量的初始化問題
指針變量同普通變量一樣,使用之前不僅要定義說明,而且必須進行初始化,指針的初始值必須是一個地址,決不允許賦予任何其他數據,通常是一個數據的地址或地址變量或空指針。
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)主調函數中就可以使用這些改變了值的變量。