当前位置: 首页 > news >正文

百度蜘蛛抓取网站模板自助建站

百度蜘蛛抓取网站,模板自助建站,网站在当地做宣传,网络直播网站开发目录 一、什么是宏以及宏的声明方式 1.宏常量: 2.宏函数: 二、宏的替换原则 三、宏设计的易犯错误 ERROR1:尾部加分号(当然有些特定需要加了分号,这里说明一般情况) ERROR2:宏函数定义时&…

目录

一、什么是宏以及宏的声明方式

1.宏常量:

2.宏函数:

二、宏的替换原则

三、宏设计的易犯错误

 ERROR1:尾部加分号(当然有些特定需要加了分号,这里说明一般情况)

ERROR2:宏函数定义时,没有保证其参数在表达式中的独立性,以及表达式的独立性

 ERROR3:带副作用的宏参数

四、#,##

1.使用# ,把一个宏参数变成对应的字符串

2.使用##,允许宏定义从分离的文本片段创建标识符

五、宏函数特性分析


前言:   

        宏,每个C语言学习者绕不开的话题,其使用简便又十分易错,稍不注意甚至处处小心仍然容易写出BUG。那么宏是什么,应该如何正确使用(减小使用错误概率)?今天让我们来一探究竟。

一、什么是宏以及宏的声明方式

        #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)

        宏的声明方式:

1.宏常量:

#define 宏常量名 宏常量值 ------- 例:#define  MAX  1000

说明:

       a.宏常量名和普通常量名没什么区别,不过习惯上使用大写字母表示

       b.语句不同成分之间用空格隔开,末尾不需要加分号

2.宏函数:

#define 宏函数名(参数列表) 宏函数表达式  ------ 例: #define  ADD  ( x, y )  ( ( x ) + ( y ) )

ps.上述函数表达式看起来很别扭,但是这是比较安全的写法,下文会进行解释。

说明:

        a.宏函数名和普通变量名没什么区别,不过习惯上使用大写字母表示

        b.语句不同成分之间用空格隔开,末尾不需要加分号

注意:
参数列表的左括号必须与宏函数名紧邻。
如果两者之间有任何空白存在,参数列表就会被解释为宏函数体的一部分。

二、宏的替换原则

        我们在设计宏和使用宏时,往往因为对宏的替换原则不够了解而出现错误,而宏的替换总结起来就是两个字——“生硬”。

        宏是在编译的阶段进行的替换,编译器会对代码进行检查,对使用了宏常量名和宏函数名的代码段将对应的常量值或函数表达式直接在原位置处嵌入式替换。

例:

#define MAX 1000
#define ADD( x, y) ( ( x ) + ( y ) )int main()
{
// 替换前printf("%d",MAX);printf("%d",ADD( 1, 2));
// 替换后printf("%d",1000);printf("%d",( ( 1 ) + ( 2 ) ));return 0;
}

        这就如同我们进行覆盖式 ctrl + c/v 一样,如此这般确实显得编译器很生硬,但这也是没有办法,毕竟语法规定,同时编译器也不能自作主张的替换,这就要求我们编程者根据特性来好好设计宏了 。       

三、宏设计的易犯错误

        了解了宏的替换原则,想必对于设计宏犯错误的原因也大概知道了,就是由于生硬的替换而导致逻辑或者语义甚至语法的错误出现。

 ERROR1:尾部加分号(当然有些特定需要加了分号,这里说明一般情况)

宏替换后, max = MAX;就变成 max = 1000;; ,这也就导致了在if else语句之间出现了一个空语句,else找不到if而落单了,这很明显是有问题的。

宏替换后,printf("%d",MAX) ;就变成了 printf("%d",1000;) ; ,这一个明眼人都能看出明显问题。

ERROR2:宏函数定义时,没有保证其参数在表达式中的独立性,以及表达式的独立性

     这里我们设计一下加法宏函数

这样的结果会是多少呢?想必根据上文提到的替换规则,应该很清楚,发生替换后,变为

5 * 2 + 3 = 13

回答正确!

那如果这样呢?还是13吗?

这时,就昏头了,是先计算宏参数值呢?还是先替换?测试瞧瞧

这是 5 * 1 + 1 + 2 + 1的结果,看来是先直接替换无疑了,这也很体现宏的“生硬”

        宏函是仿照函数的,应该和函数基本性质相同才对,而对于函数,函数参数传参时应该先计算后传入,对于函数表达式更是一个整体,全算完了才进行外部动作。

所以对于宏函数的函数表达式,我们应该用括号将参数以及函数表达式的独立性体现出来,于是我们这样定义: #define  ADD(x,y)  (( x )+( y ))

  

 ERROR3:带副作用的宏参数

        当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

这里的副作用通常是指对自身进行改变的作用。如:x + 1 与 x++

我们进行替换

结果

在进行判断后,x,y自增,选择结束后y又进行自增,所以这即便给每个参数都确保的独立性,也无法保证其正确。

四、#,##

1.使用# ,把一个宏参数变成对应的字符串

#对于宏,有这么一个技巧,可以把一个宏参数变成对应的字符串:

PRINT("%d", i + 3) 变为  printf("the value of "i + 3" is"“%d” "\n", 1 + 3) 

ps.这里还涉及printf字符串拼接的特性printf("haha""nihao") -> printf("hahanihao")

2.使用##,允许宏定义从分离的文本片段创建标识符

这样的连接必须产生一个合法的标识符,否则其结果就是未定义的。

五、宏函数特性分析

        通过上文,应该不会有人还觉得宏函数那么好干嘛还要使用普通函数了吧。

a.调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。(创建函数栈桢有内存消耗)所以宏比函数在程序的规模和速度方面更胜一筹

b.函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏可以适用于整形、长整型、浮点型等可以用于来比较的类型。宏是类型无关的。但也意味着宏没有类型检查,这在一些时候是不安全的体现。

c. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度,增加编译工作量。
d.宏在编译阶段就进行替换,是没法调试的

4. 宏可能会带来运算符优先级的问题,导致程容易出现错。

        综上宏函数适合短小计算,可以替代小型函数,但大型函数也是无能为力,对于类型检查有要求的,可以使用enum枚举常量来替代。

http://www.jinmujx.cn/news/112222.html

相关文章:

  • 政府网站 建设依据nba最新排名榜
  • 做影视网站难吗福州seo结算
  • 除了个性化阶段优化网站搜索排名
  • 网站建设技能考市场营销方案范文
  • 哪里可以做足球网站seo关键词排名优化销售
  • 做兼职的网站 知乎seo草根博客
  • 港海建设网站论坛推广的特点
  • 网站建设优化制作公司seoapp推广
  • 公司网站制作商想建立自己的网站
  • 网站创建时间查询在线视频观看免费视频22
  • 怎么查到代码是哪个网站做的人员优化是什么意思
  • 杭州市做外贸网站的公司如何推广公众号
  • 做外贸如何建网站自助网站建设
  • 做详情页哪个网站好小说排行榜2020前十名
  • 苏州专业做网站的公司有哪些如何在百度发广告推广
  • 企业营销策划的基本原则是武汉标兵seo
  • 宁波有哪家公司做网站的浙江网站推广
  • 网站备案要多久百度关键词价格查询软件
  • wordpress分类目录在衡水网站优化推广
  • 校园生活网页设计seo基础优化包括哪些内容
  • 网站设计课程总结网站收录查询系统
  • 网站在线开发网络营销的实现方式
  • 陕西网站建设托管郑州百度网站优化排名
  • 网站建设进度及实过程推广和竞价代运营
  • 中学网上做试卷的网站公司建设网站哪家好
  • 福州专业网站建设服务商2023年5月疫情爆发
  • 陕西省建设网三类人员官网站长之家seo综合查询
  • 邢台新引擎网络app优化推广
  • 乌鲁木齐市建设局网站识图搜索在线 照片识别
  • 上海建设工程咨询协会seo基础知识培训