C語言必備知識1(預處理,宏定義,內存分配)

C語言預處理

C 預處理器是一個文本替換工具

所有的預處理器命令都是以井號(#)開頭。下面列出了所有重要的預處理器指令:
指令    描述
#define    定義宏
#include包含一個源代碼文件
#undef    取消已定義的宏
#ifdef    如果宏已經定義,則返回真
#ifndef    如果宏沒有定義,則返回真
#if    如果給定條件爲真,則編譯下面代碼
#else    #if 的替代方案
#elif    如果前面的 #if 給定條件不爲真,當前條件爲真,則編譯下面代碼
#endif    結束一個 #if……#else 條件編譯塊
#error    當遇到標準錯誤時,輸出錯誤消息
#pragma    使用標準化方法,向編譯器發佈特殊的命令到編譯器中
================================================================

分塊記憶爲

define undef
if elif else endif
ifdef endif
ifndef endif
error
pragma

================================================================




C提供的三種預處理(gcc -E)功能:
文件包含
條件編譯
宏定義


-------------------------------------------------------------

什麼是宏?
宏就是替換
宏定義末尾不加分號

-------------------------------------------------------------
宏定義是C提供的三種預處理功能的其中一種,這三種預處理包括:宏定義、文件包含、條件編譯

宏定義又稱爲宏代換、宏替換,簡稱“宏”。
格式:
#define 標識符 字符串
其中的標識符就是所謂的符號常量,也稱爲“宏名”。
預處理(預編譯)工作也叫做宏展開:將宏名替換爲字符串。
掌握"宏"概念的關鍵是“換”。一切以換爲前提、做任何事情之前先要換,準確理解之前就要“換”。
即在對相關命令或語句的含義和功能作具體分析之前就要換:
例:
#define PI 3.1415926
把程序中出現的PI全部換成3.1415926
說明:
(1)宏名一般用大寫
(2)使用宏可提高程序的通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。例如:數組大小常用宏定義
(3)預處理是在編譯之前的處理,而編譯工作的任務之一就是語法檢查,預處理不做語法檢查。
(4)宏定義末尾不加分號;
(5)宏定義寫在函數的花括號外邊,作用域爲其後的程序,通常在文件的最開頭。
(6)可以用#undef命令終止宏定義的作用域
(7)宏定義不可以嵌套
(8)字符串" "中永遠不包含宏
(9)宏定義不分配內存,變量定義分配內存。
(10)宏定義不存在類型問題,它的參數也是無類型的。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------

C 內存管理
C 語言爲內存的分配和管理提供了幾個函數。這些函數可以在 <stdlib.h> 頭文件中找到。

1    void *calloc(int num, int size);該函數分配一個帶有 num 個元素的數組,每個元素的大小爲 size 字節。
2    void free(void *address);該函數釋放 address 所指向的h內存塊。
3    void *malloc(int num);該函數分配一個 num 字節的數組,並把它們進行初始化。
4    void *realloc(void *address, int newsize);該函數重新分配內存,把內存擴展到 newsize。


=================================================================

簡記:

alloc(allocate)分配

* mallac()
* calloc(num,size);
* realloc(*address,int newsize);

void free(*address);

=================================================================

Linux下對編譯後的可執行文件Test使用size命令,結果如下:

size Test
   text       data        bss        dec        hex    filename
   1197        504         16       1717        6b5    Test

可以看出,此可執行程序在存儲時(沒有調入到內存)分爲代碼區(text)、數據區(data)和未初始化數據區(bss)3個部分。


棧和堆的區別

棧是由編譯器在需要時分配的,不需要時自動清除的變量存儲區。裏面的變量通常是局部變量、函數參數等。堆是由malloc()函數(C++語言爲new運算符)分配的內存塊,內存釋放由程序員手動控制,在C語言爲free函數完成(C++中爲delete)


C程序執行時的內存分配情況如註釋所述:

//main.cpp 
int a = 0;    //a在全局已初始化數據區
char *p1;    //p1在BSS區(未初始化全局變量)
main()
{
int b;    //b在棧區
char s[] = "abc"; //s爲數組變量,存儲在棧區,
//"abc"爲字符串常量,存儲在已初始化數據區
char *p1,p2;  //p1、p2在棧區
char *p3 = "123456"; //123456\0在已初始化數據區,p3在棧區
static int c =0;  //C爲全局(靜態)數據,存在於已初始化數據區
//另外,靜態數據會自動初始化
p1 = (char *)malloc(10);//分配得來的10個字節的區域在堆區
p2 = (char *)malloc(20);//分配得來的20個字節的區域在堆區
free(p1);
free(p2);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章