1. 程式人生 > >1.如何避免野指標2.獲取字串的兩種方法。以及malloc,calloc,ralloc的使用注意點3.二維三維陣列4.陣列和函式的區別

1.如何避免野指標2.獲取字串的兩種方法。以及malloc,calloc,ralloc的使用注意點3.二維三維陣列4.陣列和函式的區別

一:野指標:

char *ptr

定一個指標,沒有賦值,用NULL

char *ptr = NULL 即表示指向空,不能再做賦值,不能對0地址操作訪問。

//#define NULL void *o

如果出現段錯誤,看看對NULL有沒有賦值。

如何避免野指標而不是杜絕:

1.如果沒有對指標進行賦值,可把指標指向空,可避免野指標

2.如果出現段錯誤,可檢視有沒有對NULL進行賦值

3.當你要把指標指向的空間賦值時,應先分配一下空間

char *ptr=hello world

*ptr=L

不對,會出現段錯誤,ptr是個常量,沒有辦法賦值。

ptr=char *malloc100*

sizeofchar);藍色部分是為了增加可移植性

指標必須是相同型別賦值,如果不是相同型別1.會越界2.取資料不完整

void*:稱為萬能指標

缺點:不能作取值操作

二:獲取字串的兩種方法。以及malloccallocralloc的使用注意點

獲取字串兩種方法

1.char ptr[100];

  1#include<stdio.h>

  2 #include<stdlib.h>

  3 #define MAX_SIZE 1024

  4 int main()

  5 {

  6     char *ptr=(char *)malloc(MAX_SIZE*sizeof(char));   malloc分配記憶體空間。

  7     if(NULL==ptr)

  8     {

  9         printf("malloc error!\n");         看記憶體是否分配成功。

 10         exit(1);

 11     }

 12         //memset(ptr,'\0',sizeof(ptr));     其中‘\0’是表示拿0來填充這100個位元組。

 13         memset(ptr,'\0',sizeof(char)*MAX_SIZE);    指把空間全部清空。

 14         //bzero(ptr,MAX_SIZE)

 15         scanf("%s",ptr);

 16         printf("ptr=%s\n",ptr);

17         free(ptr);     釋放空間。釋放以後,ptr沒值了,但是還儲存了原來的地址,      如果不置為空,會變成野指標

 18         ptr=NULL;

 19         return 0;

 20 }

malloc的標頭檔案#include<stdlib.h>

用了空間再用一次的時候一定要記得清空

通常都是先分配空間,然後檢驗空間是否分配成功,把空間裡面的殘留元素都清空,然後初始化,再釋放,最後再初始化。

通常用memset來初始化一塊記憶體。

mallocrelloccalloc的區別。

char *ptr=(char *)malloc(MAX_SIZE*sizeof(char));

char *ptr=(char *)calloc(20,sizeof(char));

1. malloc不能初始化所分配的記憶體空間,而函式calloc能。如果malloc函式分配的記憶體空間原來沒有被使用過,則其中的每一位可能都是0;反之,如果這部分記憶體曾經被分配過,則其中可能遺留各種各樣的資料,也就是說,使用malloc函式的程式開始時(記憶體還沒有被重新分配)能正常進行,但經過一段時間(記憶體已經被重新分配,可能會出現一些問題)。

2. calloc會將所分配的空間中的每一位都初始化為零,也就是說如果你是字元型別或整數型別的元素分配記憶體,那麼這些元素將保證會被動的初始化為0,如果你為指標型別的元素分配記憶體,那麼這些元素通常會被初始化為空指標。如果你為實型元素分配記憶體,則這些元素會被初始化為浮點型的0。

3. realloc可以對給定的指標所指向的空間進行擴大或縮小,無論是擴大還是縮小,原有的記憶體中的內容將保持不變對於縮小,則被縮小的那一部分的內容將會丟失,realloc並不保持調整後的記憶體空間和原來的 記憶體空間保持同一記憶體地址,realloc返回的指標很可能指向新的地址。

實現原理

malloc、calloc函式的實質體現在,它有一個將可用的記憶體連線為一個長長的連結串列(即所謂的空閒連結串列)。呼叫malloc函式時,它沿連線表尋找一個大到足以滿足使用者請求所需要的記憶體塊,然後將該記憶體塊一分為二(一塊的大小與使用者申請的大小一樣,另一塊就是剩下的位元組),接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果有的話),返回到連結串列上,呼叫free函式 時,它將使用者釋放的記憶體塊連線到空鏈上,到最後,空閒連結串列會被切成很多的小記憶體片段,如果這時使用者申請一個大的記憶體片段,那麼空閒鏈上可能沒有可能滿足使用者要求的片段了,於是malloc函式請求延時,並開始在空間中翻箱倒櫃的檢查記憶體片段,對它們進行整理,並將相鄰的小空閒塊合成較大的記憶體塊

三.指標轉換的表現形式以及二維陣列三維陣列的詳解

指標+整數:加步長

指標+指標:指兩個地址之間相差的資料型別的個數


  1#include<stdio.h>

  2 #define MAX_SIZE 3

  3 int main()

  4 {

  5     int a[MAX_SIZE]={0};

  6     int *p=a;

  7     scanf("%d",&a[i]);

  8     scanf("%d",a+i);

  9     scanf("%d",p+i);

 10     scanf("%d",p);

 11     scanf("%d",p++);

 12     scanf("%d",&p[i]);

 13     scanf("%d",a++);error 錯的因為a是陣列的首地址,沒有辦法自加。

         指標常量,儲存的是陣列a的首地址。

 14     p=a;

 15     for(i = 0; i < MAX_SIZE; i++)

 16     printf("a[%d]=%d\n",a[i]);

 17     printf("a[%d]=%d\n",p[i]);

 18     printf("a[%d]=%d\n",*(p+i));

 19     printf("a[%d]=%d\n",*(a+i));

 20     printf("a[%d]=%d\n",*(p++));

 21     printf("a[%d]=%d\n",)

 22 }

對陣列地址取值:為陣列首元素的地址

對陣列名取地址:為陣列的地址

變數存數,指標變數存的是地址

指標陣列:array of pointers,即用於儲存指標的陣列,也就是陣列元素都是指標

陣列指標:a pointer to an array,即指向陣列的指標

函式指標:儲存的函式地址

總之一句話,定義了指標一定要知道指標指向哪裡,不然要悲劇。

二維陣列可以省略列不可以省略行

二維陣列名,a代表首個一維陣列的地址。

二維陣列的單位是一個一維陣列。

scanf("%d",&a[i][j]);

printf("a[%d][%d]"=%d\n",i,j,a[i][j]);

scanf("%d",*(a+i)+j);

printf("a[%d][%d]"=%d\n",i,j,*(*(a+i)+j));

*(*(a+i)+j):

a+i:第i+1個一維陣列的地址。

*(a+i):第i+1個一維陣列首元素的地址

*(a+i)+j:第i+1個一維陣列第j+1個元素的地址

*(*(a+i)+j):第i+1個一維陣列第j+1個元素的值

三維陣列:a代表首個二維陣列的地址


*(&a)=a:為首個一維陣列的地址

*(*(*(a+i)+j)+k)

a+i:第i+1個二維陣列的地址。

*(a+i):第i+1個二維陣列的第一個一維陣列的地址

*(a+i)+j:第i+1個二維陣列的第j+1個一維陣列的地址

*(*(a+i)+j):第i+1個二維陣列第j+1個一維陣列的首元素的地址

*(*(a+i)+j)+k:第i+1個二維陣列第j+1個一維陣列第k+1個元素的地址

*(*(*(a+i)+j)+k):第i+1個二維陣列第j+1個一維陣列第k+1個元素的值

sizeof裡面存放的是位元組

[]=*()

四.

函式中傳送和接受的對應

1傳一維陣列名,用元素指標來接

2傳二維陣列名,用一維陣列指標來接

3傳三維陣列名,用二維陣列指標來接

4.指標陣列,用指標的指標來接。

void print_src(char(*src)[100])

void print_ktc(char(*ktr)[3][100])

指標就是間接性的訪問。

陣列和指標的區別:

陣列要麼在靜態儲存區被建立(如全域性陣列),要麼在棧上被建立。陣列名對應著(而不是指向)一塊記憶體,其地址與容量在生命期內保持不變,只有陣列的內容可以改變。

指標可以隨時指向任意型別的記憶體塊,它的特徵是“可變”,所以我們常用指標來操作動態記憶體。指標遠比陣列靈活,但也更危險。