国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言之預(yù)處理那點事

這篇具有很好參考價值的文章主要介紹了C語言之預(yù)處理那點事。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


在C語言中,曾出現(xiàn)各種各樣新的標(biāo)準(zhǔn),有的曇花一現(xiàn),有的則源遠(yuǎn)流傳。我們這篇來看流傳下來的,簡化開發(fā)者編程和提升性能的一種精粹“預(yù)處理”。

一、程序的翻譯和執(zhí)行環(huán)境

2.構(gòu)建我們的main函數(shù)
在ANSI C的任何一種實現(xiàn)中,存在兩個不同的環(huán)境。
第一種是翻譯環(huán)境,在這個環(huán)境中源代碼被轉(zhuǎn)換為可執(zhí)行的機器指令。
第二種為運行環(huán)境,他用于實際執(zhí)行代碼。
C語言之預(yù)處理那點事
翻譯環(huán)境有有一下幾步操作:
C語言之預(yù)處理那點事
經(jīng)過匯編過程生成目標(biāo)文件,在經(jīng)過鏈接完成翻譯環(huán)境的工作,生成一個可執(zhí)行程序文件。
當(dāng)有多個源文件時:
C語言之預(yù)處理那點事鏈接器的目的是把多個源文件生成的目標(biāo)文件進行整合,從而形成一個單一而完整的可執(zhí)行程序。
鏈接器也會引入標(biāo)準(zhǔn)C函數(shù)庫中任何被改程序所用到的函數(shù),而且他還可以搜索程序員個人的程序庫,將其需要的函數(shù)也鏈接到程序中。
C語言之預(yù)處理那點事
我們用Linux系統(tǒng)來具體的演示一下每個階段:
下面一串代碼為我們測試使用的代碼:

#include<stdio.h>
#define MAX 10
int main()
{
	int a = MAX;//給a賦值
	printf("%d", a);
	return 0;
}

預(yù)編譯階段:

gcc -E test.c > test.i//將test.c進行預(yù)編譯,并把編譯的內(nèi)容重定向到test.i中

C語言之預(yù)處理那點事我們發(fā)現(xiàn)里面的MAX變?yōu)槲覀兯x的10,且沒有我們的注釋,代碼量也從8行變?yōu)?00多行,這是對include頭文件的包含造成的。
編譯階段:

gcc -S test.i > test.s//將test.i進行編譯,并把編譯的內(nèi)容重定向到test.s中

這是在Linux下進行匯編的結(jié)果。
C語言之預(yù)處理那點事
我們也可以直接在VS上查看匯編代碼:
C語言之預(yù)處理那點事
匯編:

gcc -c test.s > test.o//將test.s進行匯編,并把編譯的內(nèi)容重定向到test.o中

C語言之預(yù)處理那點事
進行匯編是將匯編語言轉(zhuǎn)化為.o(Windows下為.obj)目標(biāo)二進制文件,且文件不可執(zhí)行。
最后進行:

gcc test.o -o test//生成test的可執(zhí)行程序,-o代表對生成的可執(zhí)行程序進行命名

C語言之預(yù)處理那點事
ls顯示當(dāng)前目錄的文件,./test為執(zhí)行該程序。
運行環(huán)境:
程序的執(zhí)行過程:
1.程序必須載入內(nèi)存中。
2.程序執(zhí)行開始,進行main函數(shù)調(diào)用。
3.開始執(zhí)行程序代碼。這個時間程序?qū)⑹褂靡粋€運行時堆棧(stack),用來存儲函數(shù)的局部變量和返回地址。程序同時也可以使用靜態(tài)(static)內(nèi)存,用來存儲他們的值
4.終止程序。正常終止main函數(shù),或者程序異常終止。

二、預(yù)定義符號的介紹

1.預(yù)定義符號

__FILE__ //進行編譯的源文件
__LINE__ //文件當(dāng)前行號
__DATE__ //文件被編譯日期
__TIME__ //文件被編譯時間

這些預(yù)定義符號都是語言內(nèi)置的。
例如:

int main()
{
	printf("file:%s\nline:%d\ndata:%s\ntime:%s", __FILE__, __LINE__, __DATE__, __TIME__);
	return 0;
}

C語言之預(yù)處理那點事

2.#define

語法:

#define name stuff

例如:

#define MAX 10
#define un unsigned //為unsigned創(chuàng)建一個更簡短的名字

替換規(guī)則:
在程序中拓展#define定義符號和宏時,需要一下幾個步驟:
1.調(diào)用宏時,先對參數(shù)進行檢查,看是否包含任何由#define定義的符號,如果有,它們首先被替換。
2.替換的文本隨后被插入到程序中原來的位置
3.最后再次對文本進行掃描,重復(fù)1,2過程。
注意:
1.宏參數(shù)和#define定義中可以出現(xiàn)其他#define定義的變量。對于宏來說,不能出現(xiàn)遞歸。
2.當(dāng)預(yù)處理器搜索#define定義的符號時,字符串常量的內(nèi)容并不被搜索。
下面我們看幾個宏的錯誤示例:

#define MAX = 10 //多了一個等號
#define MIN 1;//多了一個分號
#define ADD(x,y) x*y//x*y沒有加括號,正確應(yīng)為(x)*(y)
int main()
{
	int a = MAX;
	int b = MIN;
	ADD(5 + 1, 6 + 1);
	return 0;
}

讓我們看看進行預(yù)編譯后的結(jié)果吧:
C語言之預(yù)處理那點事
我們可看出對a進行賦值時多了一個等號,對b賦值時末尾多一個分號,進行宏替換的x和y的運算順序也和我們所想的不一樣。
宏是替換,使用宏要注意宏所編寫的是否正確。
帶副作用的宏參數(shù):
當(dāng)宏參數(shù)在宏的定義中出現(xiàn)超過一次的時間,如果參數(shù)帶有副作用,那么使用這個宏可能會出現(xiàn)危險,導(dǎo)致不可預(yù)測的后果。副作用就是表達式求值的時間出現(xiàn)的永久性效果。例如:

x+1;//不帶副作用
x++;//帶副作用

下面我們用一個具體例子來看下結(jié)果:

#define MAX(X,Y) ((X)>(Y)?(X):(Y))
int main()
{
	int a = 10;
	int b = 11;
	int max = MAX(a++, b++);
	printf("%d\n", max);
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}

C語言之預(yù)處理那點事
我們看到a和b的值發(fā)生了變化。這就是副作用宏。
#undef:用來移除一個宏定義。。

3.宏和函數(shù)的比較

上面宏定義的運算我們?yōu)槭裁床挥煤瘮?shù)來執(zhí)行呢?原因有一下兩個方面:
1.用于調(diào)用函數(shù)和函數(shù)返回的代碼的時間可能比執(zhí)行這個代碼所需更多時間。所以宏比函數(shù)在程序的規(guī)模和速度上更勝一籌。
2.函數(shù)的參數(shù)必須要指明特定的類型。而宏可以適用于任何類型。宏是和類型無關(guān)的。
宏和函數(shù)相比劣勢也很明顯:
1.每次使用宏時,需要進行宏替換,如果宏比較長,則可能大幅增加程序的長度。
2.宏是無法調(diào)試的
3.宏是和類型無關(guān)的,也就不夠嚴(yán)謹(jǐn)
4.宏可能帶來運算符優(yōu)先級的問題,導(dǎo)致程序出錯。
命名約定:
一般來說函數(shù)和宏使用語法很相似。所以語言本身無法幫我們區(qū)分。所以出現(xiàn)了命名約定。宏名全部為大寫,函數(shù)名不要全部大寫

4.條件編譯

在編譯一個程序的時間如果我們要將一條語句(一組語句)編譯或者放棄是很方便的。因為我們有條件編譯指令。比如:用來調(diào)試的代碼,頭文件是否包含等。
1:

#if 常量表達式
	//。。。。
#endif
//常量表達式由預(yù)處理器求值
#define __DEBUG__ 1
int main()
{
	int a = 0;
	#if __DEBUG__
	a = 10;
	#endif
	printf("%d", a);
	return 0;
}

2:多個分支的條件編譯條件

#if 常量表達式
	//。。。。
#elif 常量表達式
//。。。。
#endif

用法和上面相同。
3.判斷是否被定義

#if defined(symbol)
#ifdef symbol

#if !defined(symbol)
#ifdef symbol

判斷是否被定義通常用于判斷是否重復(fù)包含頭文件,#pragma once和判斷是否被定義類似。

總結(jié)

預(yù)處理可以改變程序設(shè)計環(huán)境,提高編程效率。所以學(xué)好預(yù)處理可以對我們起到錦上添花的作用。文章來源地址http://www.zghlxwxcb.cn/news/detail-478643.html

到了這里,關(guān)于C語言之預(yù)處理那點事的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C語言【預(yù)處理器】

    1、一些關(guān)于預(yù)處理的知識 ?C代碼中,一般帶 # 的都是預(yù)處理指令,包括 宏替換、文件包含、條件編譯 等。 ?為兼容一些老編譯器, # 前后一般不寫空格 ?預(yù)處理指令后面不加分號。 2、宏定義 3、文件包含 ?自定義頭文件,用\\\" \\\" 。 引號里填相對路徑或絕對路徑?;诋?dāng)

    2024年02月05日
    瀏覽(22)
  • C語言:預(yù)處理詳解

    C語言:預(yù)處理詳解

    創(chuàng)作不易,來個三連唄! C語?設(shè)置了?些預(yù)定義符號, 可以直接使? ,預(yù)定義符號也是在預(yù)處理期間處理的。 __FILE__ //進?編譯的源?件 __LINE__ //?件當(dāng)前的?號 __DATE__ //?件被編譯的?期 __TIME__ //?件被編譯的時間 __STDC__ //如果編譯器遵循ANSI C,其值為1,否則未定義

    2024年01月19日
    瀏覽(38)
  • 【C語言】預(yù)處理詳解

    【C語言】預(yù)處理詳解

    ???????? 本文目錄 1 預(yù)定義符號 2 #define 2.1 #define 定義標(biāo)識符 2.2 #define 定義宏 2.3 #define 替換規(guī)則 2.4 #和## 2.5 帶副作用的宏參數(shù) 2.6 宏和函數(shù)對比 2.7 命名約定 3 #undef 4 命令行定義 5 條件編譯 6 文件包含 6.1 頭文件被包含的方式 6.2 嵌套文件包含 這些預(yù)定義符號都是語言內(nèi)置

    2024年02月14日
    瀏覽(35)
  • 詳解C語言—預(yù)處理

    詳解C語言—預(yù)處理

    目錄 一、預(yù)處理 1、預(yù)定義符號介紹 2、預(yù)處理指令 #define #define 定義標(biāo)識符:? #define 定義宏: #define 替換規(guī)則 3、預(yù)處理操作符# 4、預(yù)處理操作符## 5、帶副作用的宏參數(shù) 6、宏和函數(shù)對比 二、命名約定 三、預(yù)處理指令 #undef 四、命令行定義 五、條件編譯? 1、單分支#if:

    2024年02月08日
    瀏覽(28)
  • C語言預(yù)處理詳解

    C語言預(yù)處理詳解

    上一篇博客中我們講了C語言的編譯與鏈接,在編譯過程中有三個小階段:預(yù)處理、編譯、匯編。 本篇博客將詳細(xì)講述預(yù)處理部分的有關(guān)知識點 。 在C語言中,C語言本身設(shè)置了?些預(yù)定義符號,可以直接使? ,預(yù)定義符號的處理也是在預(yù)處理期間進行的。 在這里介紹幾個常

    2024年04月15日
    瀏覽(39)
  • C語言·預(yù)處理詳解

    C語言·預(yù)處理詳解

    ????????C語言設(shè)置了一些預(yù)定義符號,可以直接使用,預(yù)定義符號也是在預(yù)處理期間處理的 ????????????????__FILE__ ?進行編譯的源文件 ????????????????__LINE__ ?文件當(dāng)前的行號 ????????????????__DATE__ ?文件被編譯的日期 ????????????????_

    2024年01月21日
    瀏覽(34)
  • 【C語言進階】預(yù)處理詳解

    【C語言進階】預(yù)處理詳解

    對預(yù)處理的相關(guān)知識進行詳細(xì)的介紹 ? ? ? ? ? ? ? ? ??? 豬巴戒 :個人主頁? ??????????????? 所屬專欄 :《C語言進階》 ? ? ? ? ?? 跟著豬巴戒 ,一起學(xué)習(xí)C語言?? 目錄 引言 預(yù)定義符號 #define定義常量 #define定義宏 帶有副作用的宏參數(shù) 宏替換的規(guī)則 宏函數(shù)的

    2024年01月23日
    瀏覽(26)
  • 【C語言:編譯、預(yù)處理詳解】

    【C語言:編譯、預(yù)處理詳解】

    我們都知道,一個程序如果想運行起來要經(jīng)過編譯、鏈接然后才能生成.exe的文件。 編譯?可以分解為三個過程: 預(yù)處理(有些書也叫預(yù)編譯)、 編譯 匯編 預(yù)處理階段 主要處理那些源文件中以#開始的預(yù)編譯指令。比如:#include,#define,處理的規(guī)則如下: 刪除所有的注釋

    2024年02月03日
    瀏覽(24)
  • <C語言> 預(yù)處理和宏

    <C語言> 預(yù)處理和宏

    這些預(yù)定義符號都是C語言內(nèi)置的。 舉個例子: #define 定義標(biāo)識符形式: 其中, 標(biāo)識符 是你希望定義的名稱,而 值 可以是一個數(shù)值、一個字符串或一個表達式。 例子: #define 只是進行簡單的文本替換,沒有類型檢查和錯誤檢查。 建議 #define 后面不要加分號 #define機制包括

    2024年02月14日
    瀏覽(22)
  • 自然語言之文本預(yù)處理

    自然語言之文本預(yù)處理

    概念 分詞就是將連續(xù)的字序列按照一定的規(guī)范重新組合成詞序列的過程。在英文的行文中,單詞之間是以空格作為自然分界符的,而中文只是字、句和段能通過明顯的分界符來簡單劃界,唯獨詞沒有一個形式上的分界符。分詞過程就是找到這樣分界符的過程. 作用 詞作為語言

    2024年02月06日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包