C語(yǔ)言進(jìn)階(預(yù)處理命令詳解)
1.宏定義
1.1不帶參宏
#define PI 3.14
變量名盡量大寫
1.2帶參宏
定義方式:
#define MAX(x, y) x > y ? x : y
下面的代碼運(yùn)行結(jié)果為15,顯然是錯(cuò)誤的。
#include <stdio.h>
#define JISUAN(x, y, z) x * y + z
int main(void)
{
int a = 0;
a = JISUAN(1 + 2,2 * 3,3 - 1);
printf("%d",a);
} 給變量帶上括號(hào),運(yùn)行結(jié)果是,正確做法如下:運(yùn)行結(jié)果為20。因此盡量給定義添加括號(hào)。避免計(jì)算錯(cuò)誤。
#include <stdio.h>
#define JISUAN(x, y, z) ((x) * (y) + (z))
int main(void)
{
int a = 0;
a = JISUAN(1 + 2,2 * 3,3 - 1);
printf("%d",a);
} 帶參宏和函數(shù)的區(qū)別:
| 帶參宏 | 函數(shù) |
| 帶參宏沒(méi)有參數(shù)類型、返回值、函數(shù)類型 相關(guān)概念 | 函數(shù)有參數(shù)類型、函數(shù)類型、返回值相關(guān) 概念 |
| 帶參宏只是代碼的替換,沒(méi)有調(diào)用傳參過(guò) 程 | 函數(shù)有調(diào)用、傳參過(guò)程 |
| 帶參宏是在程序編譯時(shí)展開,代碼體積增 大 | 函數(shù)是在程序運(yùn)行過(guò)程中加載,代碼體積 不會(huì)增大 |
| 帶參宏沒(méi)有傳參過(guò)程,執(zhí)行效率高 | 函數(shù)有傳參過(guò)程,需要調(diào)用、傳參產(chǎn)生資 源開銷 |
| 簡(jiǎn)單的代碼想要封裝模塊,優(yōu)先帶參宏 | 需要嚴(yán)謹(jǐn)?shù)拇a邏輯,多行代碼,考慮使 用函數(shù) |
2.頭文件的包含
#include <stdio.h> #include <string.h> #include <math.h> #include "head.h"
#include 包含一個(gè)文件,文件會(huì)在預(yù)處理編譯時(shí)展開。
<>:在系統(tǒng)目錄下查找該頭文件。
"":在當(dāng)前目錄下查找該頭文件,如果找不到再到系統(tǒng)目錄下查找頭文件。
2.1頭文件中的內(nèi)容
1.構(gòu)造數(shù)據(jù)類型的定義
2.全局變量的聲明
3.全局函數(shù)的聲明
4.宏定義
2.2工程結(jié)構(gòu)

main.c中負(fù)責(zé)主函數(shù)編寫
- 功能代碼.c中主要負(fù)責(zé)功能函數(shù)的編寫
- 功能代碼.h中主要負(fù)責(zé)聲明功能代碼.c中編寫的功能函數(shù)
- 調(diào)用函數(shù)的文件只需加對(duì)應(yīng)函數(shù)的.h頭文件即可使用該函數(shù)
這么說(shuō)可能有些不太好理解,我們來(lái)舉個(gè)例子吧:
我們先創(chuàng)建一個(gè)工程文件夾jisuan來(lái)進(jìn)行輸入兩個(gè)數(shù)字的四則運(yùn)算:

再在里面創(chuàng)建jia.c jia.h jian.c jian.h cheng.c cheng.h chu.c chu.h main.c,一個(gè).c的功能文件必須對(duì)應(yīng)一個(gè).h的頭文件聲明用來(lái)方便主文件的調(diào)用!這里main.c不需要頭文件。因?yàn)檫@里存放主函數(shù)。

創(chuàng)建好后分別對(duì)jia.cjian.c cheng.c chu.c函數(shù)進(jìn)行編寫。
- jia.c:
#include<stdio.h>
float jia(float x , float y)
{
return x + y;
}
- jian.c:
#include <stdio.h>
float jian(float x , float y)
{
return x - y;
}
- cheng.c:
#include<stdio.h>
float cheng(float x , float y)
{
return x * y;
}- chu.c:
#include<stdio.h>
extern float chu(float x , float y)
{
return x / y;
}
接下來(lái)依次編寫他們的頭文件:
- jia.h
extern float jia(float x ,float y);
jian.h
extern float jian(float x ,float y);
- cheng.h
extern float cheng(float x ,float y);
- chu.h
extern float chu(float x ,float y);
最后我們進(jìn)行主函數(shù)的編寫:這里要注意一定要用#include"函數(shù)功能.h"來(lái)聲明定義的變量
- main.c:
#include<stdio.h>
#include"jia.h"
#include"jian.h"
#include"cheng.h"
#include"chu.h"
int main(void)
{
float r1 = 0;
float r2 = 0;
float r3 = 0;
float r4 = 0;
float a = 0;
float b = 0;
scanf("%f %f",&a,&b);
r1 = jia(a,b);
r2 = jian(a,b);
r3 = cheng(a,b);
r4 = chu(a,b);
printf("jia = %f\n",r1);
printf("jian = %f\n",r2);
printf("cheng = %f\n",r3);
printf("chu = %f\n",r4);
return 0;
} ok,編寫工作完成,我們來(lái)對(duì).c文件進(jìn)行編譯:

編譯完成后就會(huì)出現(xiàn)一個(gè)可執(zhí)行文件main

我們?cè)囍\(yùn)行一下:

輸入12和45,得出計(jì)算結(jié)果。
這里,我在想這不是跟我前一篇寫的函數(shù)里extern外部聲明一樣的嘛,只不過(guò)通過(guò)#include""展開函數(shù)聲明而已。但是在未來(lái)的項(xiàng)目中撰寫每個(gè)功能代碼和主函數(shù)的不是同一個(gè)人,為了方便撰寫主函數(shù)的人調(diào)用,采用這樣的方法是不錯(cuò)的選擇。
3.條件編譯
| 關(guān)鍵字 | 功能描述 |
| #if | 如果條件為真則編譯后續(xù)代碼塊 |
| #elif | 若前面的#if或#elif條件不成立,并且該條件成立,則編譯該部分的后續(xù)代碼塊 |
| #else | 若前面的#if和#elif都不成立,則編譯該部分代碼塊 |
| #endif | 結(jié)束一個(gè)條件編譯塊,必須要與#if,#ifdef,#ifndef聯(lián)用 |
| #ifdef | 若某個(gè)宏被定義,則使用該部分代碼 |
| #ifndef | 若某個(gè)宏沒(méi)被定義,則使用該部分代碼 |
#if 1 編譯此部分 #elif 不編譯該部分 #else
#if 0 不編譯該部分 #elif 1 編譯該部分 #else test
#if 0 不編譯該部分 #elif 0 不編譯該部分 #else 編譯該部分
#if 1 編譯該部分 #endif 結(jié)束此條件編譯
#if 0 不編譯該部分 #endif 結(jié)束此條件編譯
#ifdef與#ifndef一般在項(xiàng)目測(cè)試中使用,可以在編譯時(shí)于外部定義或不定義某個(gè)宏,以此來(lái)調(diào)用代碼。
#include <stdio.h>
#define JISUAN(x, y, z) ((x) * (y) + (z))
int main(void)
{
#ifdef TEST
printf("測(cè)試\n");
#endif
#ifdef YINGYONG
printf("應(yīng)用\n");
#endif
return 0;
} 如上述代碼,對(duì)其編譯gcc -D TEST l.c -o l 在編譯的時(shí)候在外部定義了TEST,則輸出測(cè)試

如果在外部定義YINGYONG 則輸出應(yīng)用。

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Sersync+Rsync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)過(guò)程
sersync是使用c++編寫,而且對(duì)linux系統(tǒng)文 件系統(tǒng)產(chǎn)生的臨時(shí)文件和重復(fù)的文件操作進(jìn)行過(guò)濾。下面通過(guò)本文給大家分享Sersync+Rsync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)過(guò)程,需要的朋友參考下吧2017-09-09
使用c++實(shí)現(xiàn)OpenCV圖像橫向&縱向拼接
這篇文章主要介紹了使用c++實(shí)現(xiàn)OpenCV圖像橫向&縱向拼接,文中有圖像拼接函數(shù),可以實(shí)現(xiàn)如“長(zhǎng)圖拼接王”這類小程序的類似功能,大家可以將該函數(shù)封裝在軟件中自由使用2021-08-08
C語(yǔ)言完數(shù)的實(shí)現(xiàn)示例
C語(yǔ)言中的完數(shù)指的是一個(gè)正整數(shù),本文主要介紹了C語(yǔ)言完數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
C++11中的可變參數(shù)模板/lambda表達(dá)式
C++11的新特性可變參數(shù)模板能夠讓我們創(chuàng)建可以接受可變參數(shù)的函數(shù)模板和類模板,相比C++98和C++03,類模板和函數(shù)模板中只能含固定數(shù)量的模板參數(shù),可變參數(shù)模板無(wú)疑是一個(gè)巨大的改進(jìn),這篇文章主要介紹了C++11中的可變參數(shù)模板/lambda表達(dá)式,需要的朋友可以參考下2023-03-03

