十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
简单来说:宏定义又称为宏代换、宏替换,简称“宏”。宏替换是C/C++的预处理中的一部分,在C++标准中有4条规则来定义替换。
创新互联建站是一家集成都网站设计、做网站、网站页面设计、网站优化SEO优化为一体的专业的建站公司,已为成都等多地近百家企业提供网站建设服务。追求良好的浏览体验,以探求精品塑造与理念升华,设计最适合用户的网站页面。 合作只是第一步,服务才是根本,我们始终坚持讲诚信,负责任的原则,为您进行细心、贴心、认真的服务,与众多客户在蓬勃发展的市场环境中,互促共生。
规则1:实参替换。
本条规则描述带参数的宏的替换过程。
对于宏定义中的形参,在替换列表中,如果不是作为#或##的操作数,那么将对应实参完全
展开(相当于对实参进行求值),然后将替换列表中的形参替换掉.如果是#或##的操作数,
那么不进行替换。
规则2:多次扫描。
在所有的形参替换为实参后,对结果进行再次扫描,如果发现还有可替换的宏,则进行替换,
否则中止。
规则3:递归替换抑制。
如果在替换列表中发现当前正在展开的宏的名字,那么这里不进行替换.更进一步,在嵌套
的替换过程中发现已经替换过的宏的名字,则不进行替换。
规则4:递归预处理抑制。
如果替换后的结果形成预处理指令,则不执行这条预处理指令。
看几个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);
其结果分别是
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的参数传入时其中的t是
正在被展开的宏,所以根据规则3,不对这个t进行处理,保持不变,得到f(2 * (0)) + t(1)。
对于第二个,h 5)被替换为g(~5),应用规则2,被替换为f(2 * ( ~ 5))。
而m(m)首先被替换为m(w),然后应用规则2再次进行替换,但是m已经是替换过的了,所以保持
不变,只对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)
其结果分别是
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", ’\\4’) = = 0" ": @\n", s);
#include "vers2.h"
"hello";
"hello" ", world"
关键是glue和xglue.
对于glue(HIGH, LOW),首先有一个规则1的抑制,得到HIGHLOW;的结果,然后二次扫描,得到
"hello";
对于xglue(HIGH, LOW)没有抑制效果,所以对参数求值,分别得到HIGH和LOW ", world",即
glue(HIGH, LOW ", world")。
然后进行连接操作得到HIGHLOW ", world",最后再扫描一次得到"hello" ", world"
如果考虑字符串的自然的连接,就可以得到"hello, world"了。
扩展资料
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如, C preprocessor C预处理器Internet Macros(iOpus) M4(如前所述,源于ATT,捆绑于Unix)
宏定义
c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为:
#define标志符[(参数表)] 字符串
宏名
在上定义中的标志符被称为“宏名”。
宏展开
在c程序编译时将宏名替换成字符串的过程称为“宏展开”。
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用, 但在文本处理程序中应用普遍。例如,
C preprocessorC 预处理器
Internet Macros(iOpus)
M4(如前所述,源于ATT,捆绑于Unix)
参考资料来源:百度百科-宏
会出错吧,宏定义替换的是一个常数,如果是用宏来计算什么的话,也是将函数过程给放上去,得出值后被宏名替换,直接替换函数名是不可行的
A函数的源码可控吗?如果可控,把对B函数的调用改成对新实现的调用就行了。
如果A函数不是自己写的(源码不可控),会麻烦一些。例如,在支持指针的语言上,可以修改B函数入口部分的汇编代码,jmp到自己的新实现。要求B函数和你的实现原型必须完全相同。
替换函数主要有strtr(),str_repalce()这两个函数。
首先针对strtr函数第一种方式:
我们看看下面的举例:
?php
echo strtr("I Love you","Lo","lO");
?
得到的结果是:
I lOve yOu
这个结果提醒我们:
1.strtr它是区分大小写的
2.strtr的替换是很特殊的,你注意看后面那个yOu,中间的O被替换的,这显然不是我们的本意。
再举一个特殊例子,说明这个php的sttr函数的怪异
?php
echo strtr("I Love you","Love","");
?
结果是:
I Love you
什么也不会改变,所以strtr需要注意的是:
3.不能被替换为空,也就是末位那个参数不能是空字符串,当然空格是可以的。
再次举例strtr函数的另一种情况:
?php
echo strtr("I Loves you","Love","lOvEA");
?
结果是:
I lOvEs yOu
注意看第三个参数的A,在结果中并没有出现。
4.我不建议用strtr以少换多。
ok,既然这个strtr函数挺麻烦为什么还要用呢?
原因是,它的速度很快。据说,strtr 比 str_replace 快四倍。
5.能用strtr函数的时候一定要用。
第二种情况:
strtr(string,array)
6.strtr符合意愿的使用方法
?php
$table_change = array('you'='her sister');
echo strtr("I Love you",$table_change);
?
结果为:
I Love her sister
7.小技巧:你想到替换什么你就往数组加什么
比如:
?php
$table_change = array('you'='her sister');
$table_change += array('Love' = 'hate');
echo strtr("I Love you",$table_change);
?
结果是:
I hate her sister
再次提醒那个Love 写成love 是行不通的哦。
字符串取代。
语法: string str_replace(string needle, string str, string haystack);
返回值: 字符串
函数种类: 资料处理
内容说明
本函数将字符串 str 代入 haystack 字符串中,将所有的 needle 置换成 str。
下例将 %body% 以 black 取代
?php
$bodytag = str_replace("%body%", "black", "body text=%body%");
echo $bodytag;
?
格式:
[@str_replace("要替换的旧内容", "要取代原内容的新字符", $被替换内容的变量名)]
[@str_replace(array('旧1','旧2','旧3'), array('新1','新2','新3'), $被替换内容的变量名)]
[@str_replace(array('旧1','旧2','旧3'), '新内容', $被替换内容的变量名)]
实例:
多对一替换:想把内容字段里所有的p/p标签清除掉,替换成空 [@str_replace(array('p','/p'), '', $Content)]
一对一替换:想把内容字段里所有的br标签换成p [@str_replace('br', 'p', $Content)]
多对多替换:想把内容字段里的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);
这是最简单的办法。当然你也可以写打开源文件,再打开目标文件,读源文件内容,写目标文件....