【C語言】動態分配內存、voi…

程序的內存分配
一個由C/C++編譯的程序佔用的內存分爲以下幾個部分:
1、棧區(stack):由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2、全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束後由系統釋放。
3、堆區(heap):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式類似於鏈表。
4、文字常量區:常量字符串就是放在這裏的。程序結束後由系統釋放。

5、程序代碼區:存放函數體的二進制代碼。


關於內存分配的函數
以下四個函數包含在stdlib.h中。
1、malloc函數,其函數原型爲:
void * malloc(unsigned int size)
其作用是在內存的動態存儲區中分配一個長度爲size的連續空間,函數的返回值是所分配區域的第一個字節的地址。
2、calloc函數,其函數原型爲:
void * calloc(unsigned n,unsigned size)
其作用是在內存的動態存儲區中分配n個長度爲size的連續空間,一般用來保存一個數組(n爲數組元素的個數,每個數組元素長度爲size,這就是動態數組),函數返回指向所分配域的起始位置的指針。如果分配不成功,返回NULL。
3、free函數,其原型爲:
void free(void * pointer)
其作用是釋放指針變量p所指向的動態空間,使這部分空間能重新被其他變量使用。pointer應是最近一次調用calloc或malloc函數所得到的函數返回值。free函數沒有返回值。
4、realloc函數,其原型爲:
void * realloc(void * pointer,unsigned int size)
對已使用malloc函數或calloc函數獲得的動態空間進行重新分配。如果重新分配不成功,返回NULL。

void指針類型(無類型指針)
C99允許使用基類型爲void的指針類型。可以定義一個基類型爲void的指針變量(void * 型變量),它不指向任何類型的數據。在將它的值賦給另一個指針變量時由系統對它進行類型轉換,使之適合於被賦值的變量的類型。

結構體指針
即指向結構體變量的指針,一個結構體變量的起始地址就是這個結構體變量的指針。
如果把一個結構體變量的起始地址存放在一個指針變量中,那麼,這個指針變量就指向該結構體變量。

1、指向結構體變量的指針

指向結構體變量的指針,既可以指向結構體變量,也可以指向結構體數組中的元素。

如:Struct Student * pt;  //pt 可以指向struct Student 類型的變量或數組元素

如果p指向一個結構體變量stu,以下3種用法等價:

(1)sth.成員名(如:stu.num);

(2)(* p).成員名(如:(*p).num);

(3)p->成員名(如:p->num)。

成員運算符“.”的優先級高於“*”,所以()不能省去。

2、指向結構體數組的指針

如果定義p 是指向struct Student 類型對象的指針變量,

struct Student{

int num;

char name[20];

};

struct Student stu[3];

struct Student * p;

p=stu;

它用來指向一個struct Student 類型的對象(結構體數組中的一個元素stu[0]的起始地址),不應用來指向stu數組元素中的某一成員。否則,編譯時將產生警告,提示地址的類型不匹配。

如果要將某一成員的地址賦值給p ,可以用強制類型轉換。如下:

p=(struct Student *)stu[0].name

此時,p 的值是stu[0]元素的name成員的起始地址。可以用printf("%s",p);輸出stu[0]中成員name的值。之後執行printf("%s",p+1);時,輸出的是stu[1]中name的值。

3、用結構體變量和結構體變量的指針作函數的參數

將一個結構體變量的值傳遞給另一個函數,有3個方法:

(1)用結構體變量的成員作參數。如:stu[0].num,屬於單向值傳遞

(2)用結構體變量作實參。也是單向值傳遞,此種方式是將結構體變量所佔的內存單元的內容全部按順序傳遞給形參,形參也必須是同類型的結構體變量。在函數調用期間形參也要佔用內存單元。這種傳遞方式在空間和時間上開銷很大。

(3)用指向結構體變量(或數組元素)的指針作實參,將結構體變量(或數組元素)的地址傳遞給形參。這種方法是比較合理的。

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