日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

详解C语言中的#define、#undef、#indef、#ifndef、#else、#endif,#if,#elif

發(fā)布時間:2024/1/8 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解C语言中的#define、#undef、#indef、#ifndef、#else、#endif,#if,#elif 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 明示常量#define

#define為C語言的一個預處理指令,通常用于進行宏定義。每行#define(邏輯行)一般由以下三部分組成,第一部分是#define指令本身,第二部分為宏,第三部分為稱為替換列表或替換體

預處理器在發(fā)現(xiàn)程序中的宏后,會用宏等價的替換體進行替換,如在上圖中,LENGTH 將被替換為100。但值得注意的是雙引號中的宏將不會進行替換。來看下面的一個例子:

#include <stdio.h> #define LENGTH 4 #define WIDTH 5 #define NAME "張三"int main(void){printf("%d\n",LENGTH);printf("%d\n", WIDTH);printf("NAME");return 0; }

輸出結果將是:

4 5 NAME //(而不是張三)

2. 在define中使用參數(shù)

在#define中還可以使用參數(shù)創(chuàng)建作用與函數(shù)類似的類函數(shù)宏。帶有參數(shù)的宏看上去很像函數(shù),因為這樣的宏也使用圓括號。類函數(shù)宏定義的圓括號中可以有一個或多個參數(shù),隨后這些參數(shù)出現(xiàn)在替換體中,如下圖所示:

首先預處理器將所有出現(xiàn)MEAN(X,Y)的地方都替換為(((X)+(Y))/2),然后根據(jù)X,Y的值進行計算(注意預處理器不做計算,不求值,只替換字符序列)。下面我們來看一個例子:

#include <stdio.h> #define SQUARE(X) X*X #define PR(X) printf("The result is %d\n",x)int main(void){int x=5;int y=SQUARE(x);printf("SQUARE(x)的結果為:");PR(y);y=SQUARE(2);printf("SQUARE(2)的計算結果為:");PR(y);printf("SQUARE(X+2)的計算結果為:");PR(SQUARE(X+2));printf("100/SQUARE(2)的計算結果為:");printf(100/SQUARE(2));returen 0; }

輸出結果為:

SQUARE(x)的結果為:25 SQUARE(2)的計算結果為:4 SQUARE(x+2)的計算結果為:17 100/SQUARE(2)的計算結果為:100

前面兩行的結果大家應該都能想到,后面兩行有部分讀者可能會不太明白。還記得我們在上面談到的嘛,“首先預處理器將所有出現(xiàn)SQUARE(X)的地方都替換為X*X”。對SQUARE(x+2),將其替換為x+2*x+2,x值為5,由于乘號優(yōu)先級高于+號,所以結果為17,而非49,要得到正確結果我們應將宏定義寫為:

#define SQUARE(X) (X)*(X)

對100/SQUARE(2),首先將其替換為100/2*2,根據(jù)優(yōu)先級規(guī)則,從左往右對表達式求值,結果為100,而非25,要得到宏定義結果我們應將宏定義寫為:

#define SQUARE(X) (X*X)

要處理前面的兩種情況,應這樣定義:

#define SQUARE(X) ((X)*(X))

盡管如此,仍無法 避免類似SQUARE(++x)的情況,這里不再深入討論
在上面我們可以看到類函數(shù)宏雖然和函數(shù)調用看上去相似,但行為卻并不相同,函數(shù)調用在程序運行時把參數(shù)的值傳遞給函數(shù),宏調用在編譯之前把參數(shù)記號傳遞給程序,這兩個不同的過程發(fā)生在不同的時期。(務必記得預處理器不做計算,不求值,只替換字符序列

2.2 用宏參數(shù)創(chuàng)建字符串:#運算符

我們在前面提到雙引號字符串中的宏不會被替換,那么如果我們想要在字符串中包含宏參數(shù)該如何做呢?在類函數(shù)宏的替換體中,#號作為一個預處理運算符,可以把記號轉換為字符串,如#X將被轉換為”X"。來看一個例子:

#include<stdio.h> #define PSQU1(X) printf("The square of X is %d\n",((X)*(X))) #define PSQU2(X) printf("The square of " #X "is %d\n",((X)*(X)))int main(void){PSQU1(3);PSQU2(3);return 0 }

輸出結果為:

The square of x is 9 The square of 3 is 9

為什么呢?調用第一個宏時,X在雙引號中不會被替換,僅替換((X)*(X));調用第二個宏時,#X將被替換為"X",然后由于字符串的串聯(lián)特性,"X"將與"The square of “和“is %d\n"組合成"The square of X is %d\n”

2.3 預處理器粘合劑:##運算符

##運算符把兩個記號組合成一個記號,如:

#define XNAME(n) x##n

調用XNAME(n)將轉換為xn,例:

#include<stdio.h> #define XNAME(n) x##n #define PRINT_XN(n) printf("x" #n "=%d\n",x##n)int main(void){int XNAMW(1)=10;int x2=20;PRINT_XN(1);PRINT_XN(2);return 0; }

結果為:

x1=10 x2=20

2.4 變參宏:…和__VA_ARGS__

通過把宏參數(shù)列表中最后的參數(shù)寫成省略號(…)來實現(xiàn)宏參數(shù)可變,而__VA_ARGS__則出現(xiàn)在替換部分中,表明省略號代表什么,如:

#include<stdio.h> #include<math.h> #define PR(...) printf(__VA_ARGS__) #define PR2(X,...) printf(#X "," __VA_ARGS__)int main() { PR("hello\n");PR("X=%d,Y=%d\n", 6, 7);PR2(2, "2的平方為:%d\n", 4); }

結果為:

hello X=6,Y=7 2,2的平方為:4

注意:省略號只能代替最后的宏參數(shù),像下面這樣就是不行的

#define PR3(M,...N) printf(#X __VA_ARGS__ #Y)

3. undef指令

#undef指令用于”取消“已定義的#define指令。
假如有如下定義:

#define LENGTH 20

通過

#undef LENGTH

將移除上面的定義,然后即可將LENGTH定義為一個新值。即使原來沒有定義LENGTH,取消LENGTH的定義仍然有效。如果想使用一個名稱,又不確定之前是否已經(jīng)用過,可以用#undef指令取消該名字的定義

4. 條件編譯

4.1 #ifdef、#else和#endif指令

#ifdef LENGTH_H#include "test1.h"#define MAX 10 #else#include "test2.h"#define MAX 20 #endif

#ifdef指令表示如果預處理器已定義了后面的標識符LENGTH_H,則執(zhí)行#else(如果有)、#endif指令之前的所有指令并編譯C代碼,如果預處理器未定義標識符LENGTH_H,且有#else指令,則執(zhí)行#else和#endif指令之間的所有代碼
注意:#else可以沒有,但#endif必須存在

4.2 #ifndef指令

#ifndef指令和#ifdef指令的邏輯相反,#ifndef指令判斷后面的標識符是否是未定義的,常用于定義之前未定義的常量,如:

#ifndef LENGHT#define LENGTH #endif

#ifndef指令也可以和#else、#endif一起使用
通常,包含多個頭文件時,其他的文件可能包含相同的宏定義,#ifndef指令可以防止相同的宏被重復定義。在首次定義一個宏的頭文件中用#ifndef指令激活定義,隨后在其他頭文件中的定義都被忽略
#ifndef指令還有一個非常重要的用法,防止多次包含一個文件,讀者也許見過這樣的寫法:

#ifndef STACK_H #define STACK_H //省略了文件內容 #endif

這樣寫是為什么呢?
首先STACK_H是一個空宏,假如該文件被包含多次,當預處理器首次發(fā)現(xiàn)該文件被包含時,STACK_H是未定義的,所以定義STACK_H,并處理該文件的 其他部分,當預處理器第二次發(fā)現(xiàn)該文件被包含時,STACK_H是已定義的,預處理器跳過該文件的其他部分
為什么會多次包含一個文件呢,因為在大型程序中,許多被包含的文件中都包含著其他文件,所以顯示包含的文件中可能包含著已經(jīng)包含的其他文件。因為在被包含的文件中有某些項(如一些結構類型的聲明)只能在一個文件中出現(xiàn)一次,這樣就會出錯
通過#ifndef就可以避免重復,因為#ifndef和#endif之間的其他部分在第二次時不會在處理
如何保證像STACK_H這樣待測試的標識符沒有在別處定義呢?通常可以用用大寫的文件名及下劃線和大寫的H做標識符,如STACK就是文件名stack的大寫
(感興趣的讀者可以去看一下我在這篇文章中提的一個關于#ifndef的問題:
關于全局變量被定義在一個被多個.c文件包含的頭文件時出現(xiàn)錯誤)

#if和#elif指令

#if指令和if很像,#if后面跟整型常量表達式,如果表達式非零,則表達式為真,此外可以按照if else的形式使用#elif
如:

#if label==1#include "test1.h" #elif lable==2#include "test2.h" #elif lable==3#include "test3.h" #else#include "other.h" #endif

#if還有一種用法可以代替#ifdef,即#if defined (VAR)代替#ifdef VAR
#defined是一個預處理運算符(注意不要和#define搞混),如果它的參數(shù)是用#define定義過的,返回1,否則返回0,這種方法還可以和#elif一起使用

#if defined (FIRST)#include "first.h" #elif defined (SECOND)#include "second.h" #elif defined (THIRD)#include "third.h" #else#include "other.h" #endif

最后覺得這篇文章對你有幫助的讀者給個點贊加關注吧!

總結

以上是生活随笔為你收集整理的详解C语言中的#define、#undef、#indef、#ifndef、#else、#endif,#if,#elif的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。