上節課我們學習了檔案型指針的運用。這節課我們則學習了變量型指針和連結清單的學習的使用。還了解了free函數、malloc函數的應用
指向結構體變量的指針變量的定義形式與一般指針變量的定義形式相同,隻是将其指向類型定義為結構體類型即可。例如: struct person { charname[20]; char sex; int age; float height; }; struct person *p;則指針變量p,它可以指向struct person類型的結構體變量。
将一個指針變量指向一個結構體變量後,可以利用指向該結構體的的指針變量引用成員,如: (* 指針變量名).成員名以上形式也常寫成: 指針變量名->成員名其中,->為指向運算符,它是由符号“-”和“>”兩部分構成的。指向運算符的優先級和成員運算符相同,也是最高一級。
§2指向結構體數組的指針變量
指針變量可以指向整型、字元型、浮點型等基本類型數組。同樣,指針變量也可以指向結構體類型的數組。
程式L13_2.C功能:使用指向結構體數組的指針變量。
#include void main(){ struct person{ char name[20];char sex;int age;float height;}per[3]={{ "Li Ping", 'M ',20,175},{"Wang Ling", 'F ',19,162.5},{"Zhao Hui", 'M ',20,178}};struct person *p;for (p=per;pname, p->sex, p->age, p->height);}
§3連結清單的概念
連結清單是動态資料結構中最基本的形式,它的規模大小可以根據需要進行動态變化,達到合理地使用存儲空間。
連結清單有一個“頭指針”變量,用來指向連結清單的第一個元素。連結清單中的每個元素都稱為“結點”,結點包含兩部分内容:一是實際的資料資訊;二是下一結點的指針,。連結清單的最後一個元素置為“NULL”(空位址),标志連結清單結束。
一個結點可以用一個結構體類型來描述。結構體中包含若幹成員,用來表示結點的資料資訊。此外必須有一個成員是與結點類型一緻的指針,用來指向後續結點。例如,一個連結清單的結點可以定義為以下的結構體類型: struct node { int data1; float data2; struct node *next; };其中,成員next是指向結點的指針變量,它指向next所在的struct node結構體類型資料。
C系統的庫函數中提供了動态申請和釋放記憶體存儲單元的函數。
(1)malloc函數
malloc函數的原型為: void *malloc(unsigned int size)
函數的功能是:在動态存儲區域中配置設定一個size位元組的連續空間。函數的傳回值為指針,它的值是所配置設定的存儲區域的起始位址。如沒有足夠的存儲空間配置設定,則傳回0(記為NULL)值。
(2)calloc函數
calloc函數的原型為: void *calloc(unsigned int n,unsigned int size)
函數的功能是:在動态存儲區域中配置設定n個為size位元組的連續空間,并将該存儲空間自動置初值0。函數的傳回值為指針,它的值是所配置設定的存儲區域的起始位址。如配置設定不成功,則傳回0值。
(3)free函數
free函數的原型為: void free(void *ptr)
函數的功能是:釋放由ptr所指向的存儲空間。ptr的值必須是malloc或calloc函數傳回的位址。此函數無傳回值。
#include
int main()
{
FILE *fp;
if((fp=fopen("c://my/test.txt","r+"))==NULL) ()
{
printf("檔案沒有正确打開,不能往下執行了. \n");
return(1);
}
}
檔案型指針
#include
int main()
{
int*ptr; // 聲明一個int指針
intval = 1; // 聲明一個int值
ptr= &val; // 為指針配置設定一個int值的引用
intderef = *ptr; // 對指針進行取值,列印存儲在指針位址中的内容
printf("deref位址=%ld,值=%d\n",ptr, deref);
}
通過*操作符聲明了一個int指針。接着我們聲明了一個int變量并指派為1。然後我們用int變量的位址初始化我們的int指針。接下來對int指針取值,用變量的記憶體位址初始化int指針。最終,我們列印輸出變量值,内容為1。
第6行的&val是一個引用。在val變量聲明并初始化記憶體之後,通過在變量名之前使用位址操作符&我們可以直接引用變量的記憶體位址。
第8行,我們再一次使用*操作符來對該指針取值,可直接獲得指針指向的記憶體位址中的資料。由于指針聲明的類型是int,是以取到的值是指針指向的記憶體位址存儲的int值。
指針與數組
#include
int main()
{
intmyarray[4] = {1,2,3,0};
int *ptr = myarray;
printf("ptr位址=%ld,值*ptr=%d\n", ptr,*ptr);
ptr++;
printf("ptr位址=%ld,值*ptr=%d\n", ptr,*ptr);
ptr++;
printf("ptr位址=%ld,值*ptr=%d\n", ptr,*ptr);
ptr++;
printf("ptr位址=%ld,值*ptr=%d\n", ptr,*ptr);
}
C語言的數組表示一段連續的記憶體空間,用來存儲多個特定類型的對象。與之相反,指針用來存儲單個記憶體位址。數組和指針不是同一種結構是以不可以互相轉換。而數組變量指向了數組的第一個元素的記憶體位址。
一個數組變量是一個常量。即使指針變量指向同樣的位址或者一個不同的數組,也不能把指針指派給數組變量。也不可以将一個數組變量指派給另一個數組。然而,可以把一個數組變量指派給指針,這一點似乎讓人感到費解。把數組變量指派給指針時,實際上是把指向數組第一個元素的位址賦給指針。
指針與結構體
#include
struct person {
intage;
char*name;
};
int main()
{
struct person first;
struct person *ptr;
first.age = 21;
char*fullname = "full name";
first.name = fullname;
ptr= &first;
printf("age=%d, name=%s\n",first.age, ptr->name);
}
#include
#include
#include
#include
#include
main()
{
intcount,*array;
if((array=(int *) malloc(10*sizeof(int)))==NULL)
{
printf("不能成功配置設定存儲空間。");
exit(1);
}
for(count=0;count<10;count++)
array[count]=count;
for(count=0;count<10;count++)
printf("%d-",array[count]);
}
上例中動态配置設定了10個整型存儲區域,然後進行指派并列印。例中if((array=(int *) malloc(10*sizeof(int)))==NULL)語句可以分為以下幾步:
1)配置設定10個整型的連續存儲空間,并傳回一個指向其起始位址的整型指針
2)把此整型指針位址賦給array
3)檢測傳回值是否為NULL
2、free函數
由于記憶體區域總是有限的,不能不限制地配置設定下去,而且一個程式要盡量節省資源,是以當所配置設定的記憶體區域不用時,就要釋放它,以便其它的變量或者程式使用。這時我們就要用到free函數。
其函數原型是:
void free(void *p)
作用是釋放指針p所指向的記憶體區。
其參數p必須是先前調用malloc函數或calloc函數(另一個動态配置設定存儲區域的函數)時傳回的指針。給free函數傳遞其它的值很可能造成當機或其它災難性的後果。
注意:這裡重要的是指針的值,而不是用來申請動态記憶體的指針本身。例:
int *p1,*p2;
p1=malloc(10*sizeof(int));
p2=p1;
……
free(p1)
malloc傳回值賦給p1,又把p1的值賦給p2,是以此時p1,p2都可作為free函數的參數。
malloc函數是對存儲區域進行配置設定的。
free函數是釋放已經不用的記憶體區域的。
malloc函數
malloc函數的原型為:
void *malloc (unsigned int size)
其作用是在記憶體的動态存儲區中配置設定一個長度為size的連續空間。其參數是一個無符号×××數,傳回值是一個指向所配置設定的連續存儲域的起始位址的指針。還有一點必須注意的是,當函數未能成功配置設定存儲空間(如記憶體不足)就會傳回一個NULL指針。是以在調用該函數時應該檢測傳回值是否為NULL并執行相應的操作。