激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言預處理預編譯命令及宏定義詳解

C語言預處理預編譯命令及宏定義詳解

2022-01-21 14:55Bitdancing C/C++

這篇文章主要為大家介紹了C語言預處理預編譯命令及宏定義的詳解,其中包含運行環境命名約定條件及#under等基礎詳解,有需要的朋友可以借鑒參考下

.c 源程序 ----- 編譯 ----- 鏈接 ---- exe ----運行 -------->

 

程序翻譯環境和執行環境

翻譯環境:源代碼被轉換為可執行機器指令(二進制代碼)。

執行環境:用于實際執行代碼。

 

翻譯環境:詳解編譯+鏈接

C語言預處理預編譯命令及宏定義詳解

1.組成程序的每個源文件通過編譯過程分別轉換成目標代碼。

2.每個目標文件由鏈接器捆綁在一起,形成一個單一而完整的可執行程序。

3.鏈接器同時也會引入標準C函數庫中任何被該程序所用到的函數,而且他可以搜索程序員個人的程序庫,將其需要的函數也鏈接到程序。

extern聲明外部文件中的函數

C語言預處理預編譯命令及宏定義詳解

1. 編譯 ― 預處理/預編譯 test.c ---- test.i

文本操作

#include 頭文件的包含

注釋刪除:使用空格替換注釋

#define 替換,所以宏無法進行調試。

……

2. 編譯 ― 編譯 test.i ---- test.s

把c語言代碼翻譯成匯編代碼

語法分析

詞法分析

語義分析

符號匯總

3. 編譯 ― 匯編 test.s ---- test.obj

把匯編代碼轉換成二進制代碼(指令)。

形成符號表。(符號+地址)

4. 鏈接 test.obj ---- test.exe

合并段表

符號表的合并和重定位

C語言預處理預編譯命令及宏定義詳解

 

運行環境

1.程序必須載入內存中。在有操作系統的環境中:一般這個由操作系統完成。在獨立的環境中,程序的載入必須由手工安排,也可能是通過可執行代碼置入只讀內存來完成。

2.程序的執行便開始。接著便調用main函數。

3.開始執行程序代碼。這個時候程序將使用一個運行時堆棧(stack),存儲函數的局部變量和返回地址。程序同時也可以使用靜態(static)內存,存儲于靜態內存中的變量在程序的整個執行過程一直保留他們的值。

4.終止程序。正常終止main函數;也有可能是意外終止

 

預處理/預編譯詳解

預定義符號

本來就有的符號

__FILE__      //進行編譯的源文件
__LINE__     //文件當前的行號
__DATE__    //文件被編譯的日期
__TIME__    //文件被編譯的時間
__STDC__    //如果編譯器遵循ANSI C,其值為1,否則未定義

應用

printf("data: %s\n time: %s" ,__DATE__,__TIME__);

輸出

data: Jul 13 2021
time: 15:13:54

#define 定義標識符

宏和define區別,宏是有參數的。

下面是宏的聲明方式:

#define name( parament-list ) stuff

其中的 parament-list 是一個由逗號隔開的符號表,它們可能出現在stuff中

參數列表的左括號必須與name緊鄰。如果兩者之間有任何空白存在,參數列表就會被解釋為stuf的一部分。

例如

#define SQUARE(X) (X)*(X)
int main()
{
  int ret = SQUARE(5);
	return 0;
}

宏的參數是替換的,不是傳參的。

在定義宏的時候不要吝嗇括號。

 

#和##

#的作用

使用#,把一個宏參數變成對應的字符串。

把參數插入到字符串中

#define PRINT(X) printf("the value of "#X" is %d\n", X)
int main()
{
	int a = 10;
	int b = 20;
	PRINT(a);
	PRINT(b);
	return 0;
}

輸出

the value of a is 10
the value of b is 20

##的作用

## 可以把位于他兩邊的符號合成一個符號,允許宏定義從分離的文本片段創建創建標識符。

#define CAT(X,Y) X##Y
int main()
{
	int class84 = 2021;
	printf("%d\n", CAT(class, 84));
}

輸出

2021

帶副作用的宏參數

#define MAX(a, b)  ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8;
z = MAX(x++, y++);
printf("x=%d y=%d z=%d\n", x, y, z);
//輸出的結果是什么?

這里我們得知道預處理器處理之后的結果是什么:

z = ( (x++) > (y++) ? (x++) : (y++));

輸出結果

x=6 y=10 z=9

宏和函數的對比

對于上述的宏,也可以用函數實現其功能。

使用宏的優點:

1.用于調用函數和從函數返回的代碼可能比實際執行這個小型計算工作需要的時間更多,所以宏比函數在程序的規模和速度方面更勝一籌。

2.函數的參數必須聲明為特定的類型,所以函數只能在類型合適的表達式上使用。反之,這個宏可以用于整型、長整型、浮點數等等,宏是類型無關的。

使用宏的缺點:

1.每次調用宏,一份宏定義的代碼插入程序中,除非宏比較短,否則可能會大幅度增加代碼的長度。

2.宏無法調試。在預編譯(預處理)階段,已經把 # define 給替換了,已經不再是宏了。

3.宏由于類型無關,也就不夠嚴謹。

3.宏可能會帶來運算符優先級的問題,更容易導致程序出錯。

inline 內聯函數

命名約定

函數和宏語法相似,語言本身沒法幫我們區分二者。把宏名全部大寫,函數名不要全部大寫。

#undef 移除宏定義

這條指令用于移除宏定義。

如果現存的一個名字需要被重新定義,那么他的舊名字首先要被移除。

#undef NAME

命令行定義

許多C的編譯器提供了一種能力,允許在命令行中定義符號,用于在啟動編譯過程。例如:當我們根據一個源文件要編譯出不同的一個程序的不同版本的時候,這個特性有點用處。假設某個程序中聲明了一個某個長度的數組,如果機器內存有限,我們需要一個很小的數組,但是另外一個機器內存大寫,我們需要一個數組能夠大寫。

條件編譯

C語言預處理預編譯命令及宏定義詳解

#define DEBUG
#ifdef DEBUG
#endif

常見的條件編譯指令

#if 常量表達式
//...
#endif

舉例子:為真參與編譯,為假 (0)不參與編譯。

#if 1
	printf("balabala....");
#endif

二、多個分支的條件編譯

#if 常量表達式
//...
#elif 常量表達式
//...
#else
//....
#endif

舉例子

#if 1==1
#elif 2==1
#else
#endif

三、判斷是否被定義

#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol

四、嵌套指令

#if defined(OS_UNIX)
	#ifdef OPTION1  
			unix_version_option1();
	#endif
	#ifdef OPTION2 
			unix_version_option2();
	#endif
#elif defined(OS_MSDOS)
	#ifdef OPTION2 
			msdos_version_option2();
	#endif
#endif

文件包含

我們已經知道,#include指令可以使另外一個文件被編譯。就像它實際出現于#include指令的地方一樣。這種替換的方式很簡單:預處理器先刪除這條指令,并用包含文件的內容替換。這樣一個源文件被包含10次,那就實際被編譯10次。

頭文件包含的方式:

1.本地文件包含:#include "Filename"

查找策略:先在源文件所在目錄下查找,如果該頭文件未找到,編譯器就像查找庫函數頭文件一樣在標準位置查找頭文件。如果找不到就提示編譯錯誤。

2.庫文件包含:#include <Filename.h>

查找策略:查找頭文件直接去標準路徑下去查找,如果找不到就返回錯誤信息。

這樣是不是可以說,對于庫文件也可以使用“”的形式包含?

答案是肯定的,可以。但是這樣做查找的效率就低些,當然這樣也不容易區分是庫文件還是本地文件了。

wwww想到自己經常重復包含,留下了悔恨的淚水~~

出現嵌套文件包含解決方法 :條件編譯

每個頭文件開頭這樣寫:

#ifndef __TEST__H__
#define __TEST__H__
//頭文件的內容
#endif         //__TEST__H__

或者

#pragma once

就可以避免頭文件的重復引入。

總結一下:預處理階段的預處理指令:條件編譯指令 / #include / #define / #error /#pragma / ……

offsetof(宏類型,成員名字)偏移量模擬實現

C語言預處理預編譯命令及宏定義詳解

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
struct S
{
	char c1;
	int a;
	char c2;
};
#define OFFSETOF(struct_name, member_name) (int)&(((struct_name*)0)->member_name)
int main()
{
	printf("%d\n", OFFSETOF(struct S, c1));
	printf("%d\n", OFFSETOF(struct S, a));
	printf("%d\n", OFFSETOF(struct S, c2));
	return 0;
}

以上就是C語言預處理預編譯命令及宏定義詳解的詳細內容,更多關于C語言預處理預編譯命令及宏的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/Joy_Cheung666/article/details/118720459

延伸 · 閱讀

精彩推薦
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
主站蜘蛛池模板: 一级成人欧美一区在线观看 | a黄在线观看 | 日本不卡一区二区三区在线观看 | 免费一级欧美大片视频在线 | 成人羞羞视频在线观看 | 成人精品 | lutube成人福利在线观看 | 性欧美xxxx极品摘花 | 久久久久久久亚洲精品 | 亚洲精品日韩欧美 | 欧美极品免费 | 2021国产精品视频 | 国产精品久久久久久久久久久久午夜 | 国产在线导航 | 国产高潮国产高潮久久久91 | 精品三区视频 | 日夜操天天干 | 狠狠干五月天 | 99久久久久国产精品免费 | 91精品国产乱码久久久久久久久 | 亚洲自拍第二页 | 中国av免费观看 | 狠狠操精品视频 | 国产午夜免费不卡精品理论片 | 长泽雅美av| 男女无遮挡羞羞视频 | 成人在线观看免费视频 | 国产18成人免费视频 | 色综合视频 | www.99久久久 | 久久久电影电视剧免费看 | 久久成人免费网 | 色悠悠久久久久 | 操网 | 激情久久精品 | 欧美一级视频网站 | 久草在线综合网 | 欧美一级免费视频 | 黄色视屏免费在线观看 | 日产精品久久久一区二区福利 | 亚洲成人福利在线 |