簡單來說:宏定義又稱為宏代換、宏替換,簡稱“宏”。宏替換是C/C++的預(yù)處理中的一部分,在C++標準中有4條規(guī)則來定義替換。
創(chuàng)新互聯(lián)建站是一家集成都網(wǎng)站設(shè)計、做網(wǎng)站、網(wǎng)站頁面設(shè)計、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)的建站公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗,以探求精品塑造與理念升華,設(shè)計最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅持講誠信,負責(zé)任的原則,為您進行細心、貼心、認真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
規(guī)則1:實參替換。
本條規(guī)則描述帶參數(shù)的宏的替換過程。
對于宏定義中的形參,在替換列表中,如果不是作為#或##的操作數(shù),那么將對應(yīng)實參完全
展開(相當(dāng)于對實參進行求值),然后將替換列表中的形參替換掉.如果是#或##的操作數(shù),
那么不進行替換。
規(guī)則2:多次掃描。
在所有的形參替換為實參后,對結(jié)果進行再次掃描,如果發(fā)現(xiàn)還有可替換的宏,則進行替換,
否則中止。
規(guī)則3:遞歸替換抑制。
如果在替換列表中發(fā)現(xiàn)當(dāng)前正在展開的宏的名字,那么這里不進行替換.更進一步,在嵌套
的替換過程中發(fā)現(xiàn)已經(jīng)替換過的宏的名字,則不進行替換。
規(guī)則4:遞歸預(yù)處理抑制。
如果替換后的結(jié)果形成預(yù)處理指令,則不執(zhí)行這條預(yù)處理指令。
看幾個C++標準中的例子:
#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) m(f)^m(m);
其結(jié)果分別是
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * ( ~ 5)) f(2 * (0,1))^m(0,1);
對于第一個,主要在于t(t(g)(0) + t)(1)的展開。
容易計算出最外層的t的實參是f(2 * (0)) + t,而作為t的參數(shù)傳入時其中的t是
正在被展開的宏,所以根據(jù)規(guī)則3,不對這個t進行處理,保持不變,得到f(2 * (0)) + t(1)。
對于第二個,h 5)被替換為g(~5),應(yīng)用規(guī)則2,被替換為f(2 * ( ~ 5))。
而m(m)首先被替換為m(w),然后應(yīng)用規(guī)則2再次進行替換,但是m已經(jīng)是替換過的了,所以保持
不變,只對w進行替換。
#define str(s) # s
#define xstr(s) str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
x ## s, x ## t)
#define INCFILE(n) vers ## n /* from previous #include example */
#define glue(a, b) a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW "hello"
#define LOW LOW ", world"
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", ’\4’) /* this goes away */
== 0) str(: @\n), s);
#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)
其結(jié)果分別是
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) = = 0" ": @\n", s);
#include "vers2.h"
"hello";
"hello" ", world"
關(guān)鍵是glue和xglue.
對于glue(HIGH, LOW),首先有一個規(guī)則1的抑制,得到HIGHLOW;的結(jié)果,然后二次掃描,得到
"hello";
對于xglue(HIGH, LOW)沒有抑制效果,所以對參數(shù)求值,分別得到HIGH和LOW ", world",即
glue(HIGH, LOW ", world")。
然后進行連接操作得到HIGHLOW ", world",最后再掃描一次得到"hello" ", world"
如果考慮字符串的自然的連接,就可以得到"hello, world"了。
擴展資料
宏語言是一類編程語言,其全部或多數(shù)計算是由擴展宏完成的。宏語言并未在通用編程中廣泛使用,但在文本處理程序中應(yīng)用普遍。例如, C preprocessor C預(yù)處理器Internet Macros(iOpus) M4(如前所述,源于ATT,捆綁于Unix)
宏定義
c程序提供的預(yù)處理功能之一。包括帶參數(shù)的宏定義和不帶參數(shù)的宏定義。具體是指用一個指定的標志符來進行簡單的字符串替換或者進行闡述替換。形式為:
#define標志符[(參數(shù)表)] 字符串
宏名
在上定義中的標志符被稱為“宏名”。
宏展開
在c程序編譯時將宏名替換成字符串的過程稱為“宏展開”。
宏語言是一類編程語言,其全部或多數(shù)計算是由擴展宏完成的。宏語言并未在通用編程中廣泛使用, 但在文本處理程序中應(yīng)用普遍。例如,
C preprocessorC 預(yù)處理器
Internet Macros(iOpus)
M4(如前所述,源于ATT,捆綁于Unix)
參考資料來源:百度百科-宏
會出錯吧,宏定義替換的是一個常數(shù),如果是用宏來計算什么的話,也是將函數(shù)過程給放上去,得出值后被宏名替換,直接替換函數(shù)名是不可行的
A函數(shù)的源碼可控嗎?如果可控,把對B函數(shù)的調(diào)用改成對新實現(xiàn)的調(diào)用就行了。
如果A函數(shù)不是自己寫的(源碼不可控),會麻煩一些。例如,在支持指針的語言上,可以修改B函數(shù)入口部分的匯編代碼,jmp到自己的新實現(xiàn)。要求B函數(shù)和你的實現(xiàn)原型必須完全相同。
替換函數(shù)主要有strtr(),str_repalce()這兩個函數(shù)。
首先針對strtr函數(shù)第一種方式:
我們看看下面的舉例:
?php
echo strtr("I Love you","Lo","lO");
?
得到的結(jié)果是:
I lOve yOu
這個結(jié)果提醒我們:
1.strtr它是區(qū)分大小寫的
2.strtr的替換是很特殊的,你注意看后面那個yOu,中間的O被替換的,這顯然不是我們的本意。
再舉一個特殊例子,說明這個php的sttr函數(shù)的怪異
?php
echo strtr("I Love you","Love","");
?
結(jié)果是:
I Love you
什么也不會改變,所以strtr需要注意的是:
3.不能被替換為空,也就是末位那個參數(shù)不能是空字符串,當(dāng)然空格是可以的。
再次舉例strtr函數(shù)的另一種情況:
?php
echo strtr("I Loves you","Love","lOvEA");
?
結(jié)果是:
I lOvEs yOu
注意看第三個參數(shù)的A,在結(jié)果中并沒有出現(xiàn)。
4.我不建議用strtr以少換多。
ok,既然這個strtr函數(shù)挺麻煩為什么還要用呢?
原因是,它的速度很快。據(jù)說,strtr 比 str_replace 快四倍。
5.能用strtr函數(shù)的時候一定要用。
第二種情況:
strtr(string,array)
6.strtr符合意愿的使用方法
?php
$table_change = array('you'='her sister');
echo strtr("I Love you",$table_change);
?
結(jié)果為:
I Love her sister
7.小技巧:你想到替換什么你就往數(shù)組加什么
比如:
?php
$table_change = array('you'='her sister');
$table_change += array('Love' = 'hate');
echo strtr("I Love you",$table_change);
?
結(jié)果是:
I hate her sister
再次提醒那個Love 寫成love 是行不通的哦。
字符串取代。
語法: string str_replace(string needle, string str, string haystack);
返回值: 字符串
函數(shù)種類: 資料處理
內(nèi)容說明
本函數(shù)將字符串 str 代入 haystack 字符串中,將所有的 needle 置換成 str。
下例將 %body% 以 black 取代
?php
$bodytag = str_replace("%body%", "black", "body text=%body%");
echo $bodytag;
?
格式:
[@str_replace("要替換的舊內(nèi)容", "要取代原內(nèi)容的新字符", $被替換內(nèi)容的變量名)]
[@str_replace(array('舊1','舊2','舊3'), array('新1','新2','新3'), $被替換內(nèi)容的變量名)]
[@str_replace(array('舊1','舊2','舊3'), '新內(nèi)容', $被替換內(nèi)容的變量名)]
實例:
多對一替換:想把內(nèi)容字段里所有的p/p標簽清除掉,替換成空 [@str_replace(array('p','/p'), '', $Content)]
一對一替換:想把內(nèi)容字段里所有的br標簽換成p [@str_replace('br', 'p', $Content)]
多對多替換:想把內(nèi)容字段里的br換成br /, 同時p換hr,把/p全清除 [@str_replace(array('br', 'p','/p'), array('br /','hr',''), $Content)]
#include stdio.h
#define N 80
/* 請在這里填寫答案 */
void f(char *c,char a)
{
for(;*c;c++)
? if(*c='0'*c='9')
? ? ? *c=a;
}
int main(void)
{
char c[N], a;
gets(c);
scanf("%c", a);
f(c, a);
printf("%s", c);
return 0;
}
char
file[20]="copy
C:\a.txt
c:\b.txt";
system(file);
這是最簡單的辦法。當(dāng)然你也可以寫打開源文件,再打開目標文件,讀源文件內(nèi)容,寫目標文件....