C語言內存四大區域幾點總結

這裏寫圖片描述

未初始化全局變量默認值爲0,未初始化局部變量一般默認值爲隨機數,但有的編譯器也爲0。

一、棧:

  棧遵循後進先出,棧的大小由編譯器決定。

  • 一般來說,默認棧的大小爲1M,所以如果變量分配內存過大可能會造成棧溢出。比如: 定義一個數組長度爲200M,double a[1024*1024*200]如果編譯器棧大小不夠的話會造成溢出。

  • 棧不同於堆,棧用完立即回收,所有局部變量都存放在棧中。
    如下程序會一直進行分配與回收,該程序運行起來會很消耗CPU

while(1)
{
    double  arr[1024*200];
}

計算機中計算是由CPU來完成的,而計算結果保存在內存中,所以a+1=2 這種賦值方式是錯誤的。


二、堆區:

內存分配函數有:malloc calloc realloc
分配的內存不會自動釋放,需要配合free()使用。如果執行內存分配以後不釋放,則會造成內存泄漏,嚴重的話會把內存分配完導致計算機崩潰。

用指針寫for循環:

 #include <stdio.h>
 #include <stdlib.h>
 void main()
 {
     int *p = (int *) malloc(sizeof(int)*10);
     int num=0;
     int *px=p;  
     for(;px<p+10;px++)
     {
         *px=num;
         printf("%p\n,%d\n",px,*px);
         num++;
     }
}

注意:

指針本身是一個變量,他存放在棧區(&p)
指針所指向的地址存放在堆區(p)


三、代碼段:

  存放函數的執行代碼。例如:函數名(函數的入口地址),以及函數的參數。

常量位於代碼區,代碼區都是隻讀的。

1、函數指針的定義:

把函數名挖掉,用 (*p) 代替。

例如:void (*pfuc) ( 參數) =fuc; (fuc爲函數名)
間接調用: pfuc(參數);

以上兩個式子等價於:直接調用fuc(參數)

2、關於const

#define N 10 宏定義有CPU產生,N不可取地址

const修飾的數據是一個僞常量(只讀常量),只是限定編譯器儘量不修改它修飾的變量,其實是可以間接修改的。

- const在前面

   const int nValue;   //nValue是const

   const char *pContent; //*pContent是const, pContent可變

   const char* const pContent;  //pContent和*pContent都是const

const在後面,與上面的聲明對等

    int const nValue; //nValue是const

    char const * pContent; //*pContent是const, pContent可變

    char* const pContent; //pContent是const,*pContent可變

    char const* const pContent; //pContent和*pContent都是const
const int num=10;
int data[10];      //不合法的,因爲num是個僞常量(只讀常量)

解析:常量是被編譯器放在內存中的只讀區域,當然也就不能夠去修改它。而”只讀變量”則是在內存中開闢一個地方來存放它的值,只不過這個值由編譯器限定不允許被修改。C語言關鍵字const就是用來限定一個變量不允許被改變的修飾符(Qualifier)。上述代碼中變量n被修飾爲只讀變量,可惜再怎麼修飾也不是常量。而ANSI C規定數組定義時長度必須是”常量”,”只讀變量”也是不可以的,”常量”不等於”不可變的變量”。但是在C++中,局部數組是可以使用變量作爲其長度的。

間接修改const修飾數據的值:
所以可以用一個指針指向num,然後就可以通過指針來修改num的值了。

 #include <stdio.h>
 int main()
 {
     const int num=10;
     int *p=(int *)&num;
     *p=100;
     printf("%d",num);
 }

四、關於靜態變量,局部變量,全局變量,外部變量:

  • 對於局部變量:未初始化也叫定義,所以不能對一個變量申明兩次。
  • 對於全局變量:定義=申明+賦值。所以如果沒有初始化只能叫做申明,所以可多次申明同一個變量,雖然沒有什麼意義。
  • 靜態變量和局部變量的區別:靜態變量被限定在本C文件中才可以使用。

  • 全局變量和外部變量,如下:

 //test1.c
 int a=2;


 //test2.c
 #include <stdio.h>
  //int a;      函數體外部只需要申明即可以,但是不能給a賦值,否則就是重定義
  void main()
  {
      extern int a;   //在函數體內部調用其他文件的全局變量,需要用extern申明
      printf("%d",a);
  }  

這裏寫圖片描述

參數入棧順序:從左往右
這裏寫圖片描述

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