C++預處理器

預處理器是一些指令,指示表一起在實際編譯之前所需要完成的預處理。

所有的預處理器指令都是以井號(#)開頭,只有空格字符可以出現在預指令處理之前。預處理指令不是C++語句,所以他們不會以分號(;)結尾。

?

#define預處理

#define預處理指令用于創建符號常量。該符號常量通常稱之為宏,指令的一般行為為

#define macro-name replacement-text

當這行代碼出現在一個文件中,在該文件中后續出現的所有宏都會在程序編譯之前被替換成成replacement-text。

/***
define.cpp
***/
#include<iostream>
using namespace std;#define PI 3.14159int main()
{cout << "Value of PI :" << PI << endl;return 0;
}

使用-E選項進行編譯,并把結果重定向到define.p 現在查看一下相關信息:

exbot@ubuntu:~/wangqinghe/C++/20190816$ gcc -E define.cpp > define.p

條件編譯

有幾個指令可以用來有選擇地對部分程序源代碼進行編譯,這個過程稱之為條件編譯。

條件預處理器地結構與if選擇結構很像。

#ifdef NULL#define NULL 0
#denif

在調試時進行編譯,調試開關可以使用一個宏來實現

#ifdef DEBUGcerr << “Variable x = ” << x << endl;
#endif

如果在指令 #ifdef DEBUF 之前定義了符號常量,則會對程序中cerr語句進行編譯。可以使用 #if 0 語句注釋掉程序的一部分。

#if 0 不進行編譯的代碼
#endif

實例:

/***
ifdef.cpp
***/
#include<iostream>
using namespace std;
#define DEBUG#define MIN(a,b) (((a) < (b)) ? a : b)int main()
{int i,j;i = 100;j = 20;
#ifdef DEBUGcerr << "Trace: Inside main function" << endl;
#endif#if 0cout << "MKSTR(HELLO C++)" << endl;
#endifcout << "The minimum is " << MIN(i,j) << endl;#ifdef DEBUGcerr << "Trace: Comint out of main function" << endl;
#endifreturn 0;
}

運行結果:

exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ ifdef.cpp -o ifdef

exbot@ubuntu:~/wangqinghe/C++/20190816$ ./ifdef

Trace: Inside main function

The minimum is 20

Trace: Comint out of main function

#和##運算符

#和##預處理運算符在C++和ANSI/ISO C中都是可用的

#運算符會把repalcement-text令牌轉換成引號引起來的字符串

/***
pound.cpp
***/
#include<iostream>
using namespace std;#define MKSTR(x) #xint main()
{cout << MKSTR(HELLO C++) << endl;return 0;
}

運行結果:

exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ pound.cpp -o pound

exbot@ubuntu:~/wangqinghe/C++/20190816$ ./pound

HELLO C++

?

C++預處理器把下面這行

cout << MKSTR(HELLO C++) << endl;

轉化成了:

cout << “HELLO C++” << endl;

##運算符用于連接兩個令牌

#define CONCAT(x,y) x ## y

當CONCAT出現在程序中,他的參數機會被連接起來,并用來取代宏,程序中CONCAT(HELLO C++)會被替換成“HELLO C++”如下圖:

/***
concat.cpp
***/
#include<iostream>
using namespace std;#define concat(a,b) a##b
int main()
{int xy = 100;cout << concat(x,y) << endl;return 0;
}

運行結果:

exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ concat.cpp -o concat

exbot@ubuntu:~/wangqinghe/C++/20190816$ ./concat

100

?

C++預處理器把下面這行:

cout << concat(x,y) << endl;

轉化成了:

cout << xy;

C++中的預定義宏

?

C++提供了下表所示的一些預定義宏:

描述

__LINE__

這會在編譯時包含當前行號

__FILE__

這會在編譯時包含當前文件名

__DATA__

這會包含一個形式為month/day/year的字符串,它表示把源文件轉換成目標代碼的日期

__TIME__

這會包含一個形式為hour:minute:second的字符串,它表示程序被編譯的時間

?

實例:

/***
macro.cpp
***/
#include<iostream>
using namespace std;int main()
{cout << "Value of __LINE__ :" << __LINE__ << endl;cout << "Value of __FILE__ :" << __FILE__ << endl;cout << "Value of __DATE__ :" << __DATE__ << endl;cout << "Value of __TIME__ :" << __TIME__ << endl;return 0;
}

運行結果:

exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ macro.cpp -o macro

exbot@ubuntu:~/wangqinghe/C++/20190816$ ./macro

Value of __LINE__ :6

Value of __FILE__ :macro.cpp

Value of __DATE__ :Aug 16 2019

Value of __TIME__ :14:06:20

# 和 ## 運算符

# 字符串化的意思,出現在宏定義中的#是把跟在后面的參數轉換成一個字符串。

當用作字符串化操作時,# 的主要作用是將宏參數不經擴展地轉換成字符串常量。

?宏定義參數的左右兩邊的空格會被忽略,參數的各個 Token 之間的多個空格會被轉換成一個空格。

?宏定義參數中含有需要特殊含義字符如"或\時,它們前面會自動被加上轉義字符 \。

## 連接符號,把參數連在一起。

將多個 Token 連接成一個 Token。要點:

?

?它不能是宏定義中的第一個或最后一個 Token。

?前后的空格可有可無。

?

轉載于:https://www.cnblogs.com/wanghao-boke/p/11363571.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384869.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384869.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384869.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++信號處理

信號是由操作系統傳給進程的中斷&#xff0c;會提早終止一個程序。在UNIX、LINUX、Mac OS或windows系統上&#xff0c;可以通過按Ctrlc產生中斷。有些信號不能被程序捕獲&#xff0c;但是下表所列信號可以在程序中被捕獲&#xff0c;并可以基于信號采取適當的動作。這些信號是定…

Python—“helloworld”

接觸一門計算機新語言&#xff0c;第一件事就是要準備好一個編譯器用來打代碼。 網上很多環境搭建的方法&#xff0c;具體參照https://www.runoob.com/python/python-install.html 由于我之前一直在使用Ubuntu的gcc編譯&#xff0c;恰好也可以運行python程序&#xff0c;我也就…

創建線程

pthread_self函數 獲取線程ID。其作用對應進程中 getpid() 函數。 pthread_t pthread_self(void); 返回值&#xff1a;成功&#xff1a;0&#xff1b; 失敗&#xff1a;無&#xff01; 線程ID&#xff1a;pthread_t類型&#xff0c;本質&#xff1a;在Linux下為無符號…

C/C++頭文件

C/C頭文件一覽C、傳統 C#include <assert.h> //設定插入點#include <ctype.h> //字符處理#include <errno.h> //定義錯誤碼#include <float.h> //浮點數處理#include <fstream.h> //文件輸入&#xff0f;輸出#include <iomanip.h> //參數化…

Python變量類型

變量存儲在內存中的值&#xff0c;這就意味著在創建變量時會在內存開辟一個空間。 基于變量的數據類型&#xff0c;解析器會分配指定內存&#xff0c;并決定什么數據可以被存儲在內存中。 因此變量可以指定不同的數據類型&#xff0c;這些變量可以存儲整數、小數、或字符。 變量…

線程退出

pthread_exit函數 將單個線程退出 void pthread_exit(void *retval); 參數&#xff1a;retval表示線程退出狀態&#xff0c;通常傳NULL 思考&#xff1a;使用exit將指定線程退出&#xff0c;可以嗎&#xff1f; …

線程分離

pthread_detach函數 實現線程分離 int pthread_detach(pthread_t thread); 成功&#xff1a;0&#xff1b;失敗&#xff1a;錯誤號 線程分離狀態&#xff1a;指定該狀態&#xff0c;線程主動與主控線程斷開關系。線程結束后&#xff0c;其退出狀態不由其他線程獲取&#x…

線程知識點

控制原語對比 進程 線程 fork pthread_create exit pthread_exit wait pthread_join kill pthread_cancel getpid pthread_self 命名空間 線程屬性 本節作為指引性介紹&…

讀寫鎖

讀寫鎖 與互斥量類似&#xff0c;但讀寫鎖允許更高的并行性。其特性為&#xff1a;寫獨占&#xff0c;讀共享。 讀寫鎖狀態&#xff1a; 一把讀寫鎖具備三種狀態&#xff1a; 1. 讀模式下加鎖狀態 (讀鎖) 2. 寫模式下加鎖狀態 (寫鎖) 3. 不加鎖狀態 讀寫鎖特性&#xff1a; 讀…

條件變量

條件變量&#xff1a; 條件變量本身不是鎖&#xff01;但它也可以造成線程阻塞。通常與互斥鎖配合使用。給多線程提供一個會合的場所。 主要應用函數&#xff1a; pthread_cond_init函數 pthread_cond_destroy函數 pthread_cond_wait函數 pthread_cond_timedwait函數 pthread_c…

文件鎖

借助 fcntl函數來實現鎖機制。 操作文件的進程沒有獲得鎖時&#xff0c;可以打開&#xff0c;但無法執行read、write操作。 fcntl函數&#xff1a; 獲取、設置文件訪問控制屬性。 int fcntl(int fd, int cmd, ... /* arg */ ); 參2&#xff1a; F_SETLK (struct flock *) 設置…

進程間同步

互斥量mutex 進程間也可以使用互斥鎖&#xff0c;來達到同步的目的。但應在pthread_mutex_init初始化之前&#xff0c;修改其屬性為進程間共享。mutex的屬性修改函數主要有以下幾個。 主要應用函數&#xff1a; pthread_mutexattr_t mattr 類型&#xff1a; 用于定義…

Python3字符串

字符串是Python中最常用的數據類型&#xff0c;可以使用單引號或雙引號來創建字符串 創建字符串很簡單&#xff0c;為變量分配一個值即可。 val1 ‘hello world’ var2 “Runoob” Python訪問字符串的值 Python不支持單字符類型&#xff0c;單字符在Python中也是作為 一個字符…

服務器客戶端編程

server 下面通過最簡單的客戶端/服務器程序的實例來學習socket API。 server.c的作用是從客戶端讀字符&#xff0c;然后將每個字符轉換為大寫并回送給客戶端。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #incl…

Python3元組

Python的元組與列表相似&#xff0c;不同之處在于元組的元素不能修改 元組使用小括號&#xff0c;列表使用方括號 元組創建很簡單&#xff0c;只需要在括號中添加元素&#xff0c;并使用逗號隔開即可。 創建空元組 tup1 (); tup2 (1,) 元組只包含一個元素時&#xff0c;需要在…

Python3字典

字典是另一種可變容器模型&#xff0c;可存儲任意類型的對象。 字典的每個鍵值(key>value)對用冒號分隔&#xff0c;每個對之間用逗號分隔&#xff0c;整個字典包括在花括號里&#xff0c;格式如下 d {key1 : value,key2 : value2} 鍵必須是唯一&#xff0c;但值則不必。 值…

線程回收

pthread_join函數 阻塞等待線程退出&#xff0c;獲取線程退出狀態 其作用&#xff0c;對應進程中 waitpid() 函數。 int pthread_join(pthread_t thread, void **retval); 成功&#xff1a;0&#xff1b;失敗&#xff1a;錯誤號 參數&#xff1a;thread&#xff1a;線…

Python3數字

Python3數字數據類型用于存儲數值。 數據類型是不允許改變的&#xff0c;這就意味著&#xff0c;如果改變數字數據類型的值&#xff0c;將重新分配內存空間。 Python支持三種不同不同的數值類型&#xff1a; 整型&#xff08;int&#xff09;&#xff1a;通常是被稱為整型或整數…

多進程服務器

注意&#xff1a;包含了“wrap.c” 和“wrap.h”文件在上篇博客中 /*** server.c ***/ #include<stdio.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<signal.h> #include<sys/wait.h> #include<ctype…

服務器之select

select select能監聽的文件描述符個數受限于FD_SETSIZE,一般為1024&#xff0c;單純改變進程打開的文件描述符個數并不能改變select監聽文件個數解決1024以下客戶端時使用select是很合適的&#xff0c;但如果鏈接客戶端過多&#xff0c;select采用的是輪詢模型&#xff0c;會大…