Android For JNI(四)——C的數組,指標長度,堆記憶體和棧記憶體,malloc,學生管理系統

來源:互聯網
上載者:User

標籤:

Android For JNI(四)——C的數組,指標長度,堆記憶體和棧記憶體,malloc,學生管理系統

好幾天每寫JNI了,現在任務也越來越重了,工作的強度有點高,還有好幾個系列的部落格要等著更新,幾本書還嗷嗷待哺的等著我去看,github上的兩個散漫的開源,基礎入門的視頻也在錄製,還要學習新的知識,
都是一種挑戰,不知道為何,最近懶散了,看來還得再加把勁,今天我們繼續延伸一下C的一些小知識

一.數組

C的數組和JAVA也是類似的,我們寫一段小程式

#include <stdio.h>    #include <stdlib.h>   main(){         char c [] ="lgl";                  //列印 每個元素的地址         printf("%#x\n",&c[0]);         printf("%#x\n",&c[1]); a        printf("%#x\n",&c[2]);         printf("%#x\n",&c[3]);         //讓視窗停留         int age ;         scanf("%d",&age);   }

我們列印一下這個數組的每個元素的記憶體位址,會驚奇的發現記憶體位址是連續的

我們繼續理解

  //列印C的地址  printf("%#x\n",&c); 

我們列印C的地址

得到的結論是第一個記憶體位址,由此我們歸納

  • 數組的記憶體空間是連續的
  • 陣列變數儲存的是第0個元素的地址
        //字元數組的地址,就是一個字元的地址         char* p = &c;        printf("第0個元素的值%c\n",*(c + 0));        printf("第0個元素的值%c\n",*(c + 1));        printf("第0個元素的值%c\n",*(c + 2));

這裡,我們就可以拿到lgl這是哪個數了
當然,如果是int類型的話,就需要位移四個單位了

二.指標長度

指標我們可以存地址,我們要想知道他的長度有多長,我們就得去測試一下

#include <stdio.h>    #include <stdlib.h>   main(){      printf("int*的長度是%d\n",sizeof(int*));      printf("double*的長度是%d\n",sizeof(double*));          //讓視窗停留       int age ;       scanf("%d",&age);}

輸出的結果

指標長度為4,因為32位的環境,記憶體長度為4,足夠了

三.堆記憶體和棧記憶體

JAVA也有類似的說法,我們定義一個變數,就在記憶體中開闢一個控制項,那具體開闢在哪呢,這就要看我們的類型了,我這裡畫張圖,好理解一下

在JAVA中,我們定義一個變數比如int i是在棧記憶體開闢控制項,persion p 也是,但是我們new了之後,對象是在堆記憶體裡。在C中,我們沒有new,我們有一個申請記憶體的函數malloc,但是java也有其他的因果,比如我們寫個數組,其實k就在棧記憶體,但是數組對象卻在堆記憶體

堆和棧的區別:
  • 1.申請方式

    棧:
    由系統自動分配.例如,聲明一個局部變數int b; 系統自動在棧中為b開闢空間.例如當在調用涵數時,需要儲存的變數,最明顯的是在遞迴調用時,要系統自動分配一個棧的空間,後進先出的,而後又由系統釋放這個空間.
    堆:
    需要程式員自己申請,並指明大小,在c中用malloc函數
    如char* p1 = (char*) malloc(10); //14byte
    但是注意p1本身是在棧中的.

  • 2 申請後系統的響應

    棧:只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢出。
    堆:首先應該知道作業系統有一個記錄空閑記憶體位址的鏈表,當系統收到程式的申請時, 會遍曆該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本記憶體空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。

  • 3.申請大小的限制

    棧:在Windows下,棧是向低地址擴充的資料結構,是一塊連續的記憶體的地區。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在WINDOWS下,棧的大小是2M(vc編譯選項中可以設定,其實就是一個STACK參數,預設2M),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
    堆:堆是向高地址擴充的資料結構,是不連續的記憶體地區。這是由於系統是用鏈表來儲存的空閑記憶體位址的,自然是不連續的,而鏈表的遍曆方向是由低地址向高地址。堆的大小受限於電腦系統中有效虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。

  • 4.申請效率的比較:

    棧:由系統自動分配,速度較快。但程式員是無法控制的。
    堆:由malloc/new分配的記憶體,一般速度比較慢,而且容易產生記憶體片段,不過用起來最方便.

  • 5.堆和棧中的儲存內容

    棧:在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。
    當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指標指向最開始存的地址,也就是主函數中的下一條指令,程式由該點繼續運行。
    堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容有程式員安排。

  • 6.記憶體的回收

    棧上分配的記憶體,編譯器會自動收回;堆上分配的記憶體,要通過free來顯式地收回,否則會造成記憶體流失。
    堆和棧的區別可以用如下的比喻來看出: \
    使用棧就像我們去飯館裡吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
    使用堆就像是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。

四.malloc

既然瞭解了,那我們就來使用malloc申請堆記憶體

#include <stdio.h>    #include <stdlib.h>   main(){                    //比如存三個int  int是4位的  所以寫12 這12個位元組的記憶體位址是連續的,       //他返回 的是堆記憶體的首地址        int* p = malloc(3 * sizeof(int));        //賦值       *(p + 1) = 3;        //列印值         printf("%d\n",*(p+1));   // = 3?        //列印地址        printf("%#x\n",(p+1));         //讓視窗停留         int age ;         scanf("%d",&age);      }

我們輸出結果

申請之後怎麼釋放呢?

    //釋放堆記憶體    free(p); 

我們可以嘗試一下釋放

#include <stdio.h>    #include <stdlib.h>   main(){                    //比如存三個int  int是4位的  所以寫12 這12個位元組的記憶體位址是連續的,       //他返回 的是堆記憶體的首地址        int* p = malloc(3 * sizeof(int));        //賦值       *(p + 1) = 3;        //列印值         printf("%d\n",*(p+1));   // = 3?        //列印地址        printf("%#x\n",(p+1));         //釋放堆記憶體        free(p);         //列印值         printf("%d\n",*(p+1));   // = 3?        //列印地址        printf("%#x\n",(p+1));         //讓視窗停留         int age ;         scanf("%d",&age);      }

我們會發現,記憶體釋放了之後,值就變了,當然記憶體不可能被釋放,而且P一直指向的是棧記憶體

五.後台管理系統

我們這裡寫個小例子,說起來這麼高大上,其實就是一段小程式,學號管理id小程式,我們玩玩

程式本身還是很簡單的,就是把前面幾篇的小知識柔和在了一起

#include <stdio.h>    #include <stdlib.h>   main(){                     printf("請輸入班級人數:");                 int count ;         scanf("%d",&count);        //有多少個人就有多少個學號         int i ;        //申請堆記憶體 儲存學號        int* p = malloc(count * sizeof(int));         for(i = 1; i <= count; i++){           printf("請輸入第%d個學生的學號:",i);              scanf("%d",(p + i - 1));          }     // 列印所有的學號      for(i = 1; i <= count; i++){           printf("第%d個學生的學號是%d\n",i,*(p+i-1));        }        int age ;        scanf("%d",&age);       system("pause");}

運行一下就知道效果了

當然,我們既然是管理系統,插入嘛,我們繼續往下寫
我們這裡會接觸到一個新的API,我們看下去

#include <stdio.h>    #include <stdlib.h>   main(){                     printf("請輸入班級人數:");                 int count ;         scanf("%d",&count);        //有多少個人就有多少個學號         int i ;        //申請堆記憶體 儲存學號        int* p = malloc(count * sizeof(int));         for(i = 1; i <= count; i++){           printf("請輸入第%d個學生的學號:",i);              scanf("%d",(p + i - 1));          }    //插入     printf("請輸入要插入的人數:");     int newCount;    scanf("%d",&newCount);    //重新申請堆記憶體     //在原有的記憶體中擴充新的空間     //當然,前提要確定可不可以擴充,如果記憶體被暫用,系統會自動分配記憶體     //新記憶體會把舊記憶體拷貝過去,並且釋放舊的記憶體     p = realloc(p,(count + newCount) * sizeof(int));      for(i = count+1; i <= count+newCount; i++){           printf("請輸入第%d個學生的學號:",i);              scanf("%d",(p + i - 1));          }     // 列印所有的學號      for(i = 1; i <= count + newCount; i++){           printf("第%d個學生的學號是%d\n",i,*(p+i-1));        }        int age ;        scanf("%d",&age);       system("pause");}

這裡注意的就是realloc了,注釋也很明了的解析了,我們運行一下

OK,暫時學到這裡!!

Android For JNI(四)——C的數組,指標長度,堆記憶體和棧記憶體,malloc,學生管理系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.