個人學習随筆,僅做學習之用
1)類型
i)宏定義 #define
ii)頭檔案包含 #include
iii)條件編譯 #if 0 #endif
iv)列印錯誤資訊 #error
2)格式
i)以“#”開頭,預處理辨別
ii)單獨書寫一行
iii)沒有分号做結尾
【1】宏定義
#define #undef
不做文法檢查,隻是簡單的替換。
注意:宏定義是簡單的替換,不占記憶體空間。
格式:
#define <宏名> <宏體>
宏名:一般大寫
宏體:可以省略,如果省略,就代表這個宏在别的地方定義過。
1)無參宏定義
#define N 10
#define N
#define STR "1234567890"
#define STR1 "123456789012345678901234567890\ //如果語句太長,可以用'\'進行換行。
1234567890"
2)帶參宏定義 可以做簡單的計算,替換簡單的函數
#define MAX(a,b) (a)>(b)?(a):(b) //在宏體部分,ab表達式最好加上(),因為宏隻做簡單替換
#define MUL(a,b) (a)*(b)
3)#undef 取消宏定義
格式:
#undef 宏名
例子:
#define N 10
#undef N
宏定義的有效範圍:
1)如果沒有#undef,整個.c檔案
2)如果有#undef,從 #define 到 #undef
【2】頭檔案包含
#include <stdio.h> :從标準庫目錄中查找頭檔案 /usr/include
#Include "fun.h" :從指定目錄查找頭檔案,如果沒有查到,就到标準庫目錄中查找
【3】條件編譯
1)#if - #elif - #else - #endif
#if 常量
#endif
注意:
i)#if和#endif是成對出現的,有#if一定有#endif
ii)#if後面必須跟常量,無參宏定義,不能是變量
#define STM32 0
#define DAHUA 0
#define HAISI 1
#if STM32
//stm32初始化
printf("stm32\n");
#elif DAHUA
//dahua初始化
printf("DAHUA\n");
#else
//HAISI初始化
printf("HAISI\n");
#endif
2)#ifndef #ifdef #endif
#ifndef :如果沒有宏定義
#ifdef :如果宏定義了
通常用于頭檔案書寫,防止頭檔案重複包含
【4】列印錯誤資訊 #error
無論是否有實際錯誤,#error指令都會讓預處理器發出錯誤消息
#error "錯誤文本資訊"
#ifndef TEST
#error "22222222"
#endif
【5】輔助調試的宏
__LINE__ 列印行号;
__FUNCTION__ 列印函數名;
__func__ 列印函數名;
__FILE__ 列印檔案名;
printf("%d %s %s\n", __LINE__, __func__, __FILE__);
【6】以定義一個不易發生錯誤的記憶體配置設定器舉例
alloc.h
/*定義個不易發生錯誤的記憶體配置設定器alloc.h*/
#include <stdlib.h>
#define malloc //不要直接使用malloc
/*
用于防止由于其他代碼塊直接塞入程式而導緻的偶爾直接調用malloc的行為,增加這個指令以後,
如果程式偶爾調用了malloc,程式将由于文法錯誤而無法編譯,
在alloc中必須加入#undef指令,這樣才能調用malloc而不至于出錯。
*/
#define MALLOC(num,type)(type*)alloc((num)*sizeof(type))
extren void *alloc(size_t size); //extern備援
/*不易發生錯誤的記憶體配置設定器的實作alloc.c*/
#include <stdio.h>
#include "alloc.h"
#undef malloc
void *alloc(size_t size){
void *new_mem;
/*請求所需的記憶體,并檢查确實配置設定成功*/
new_mem = malloc(size);
if(new_mem == NULL){
printf("out of memory!");
exit(1);
}
return new_mem;
}
/*一個使用很少引起錯誤的記憶體配置設定器的程式a_client.c*/
#include "alloc.h"
void function(){
int *new_memory;
/*獲得一串整型空間*/
new_memory = MALLOC(25,int);
}