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

佛山网站开发哪家好网络营销推广

佛山网站开发哪家好,网络营销推广,wordpress 编辑器,什么是独立网站做外贸目录 一.预定义符号 二.#define定义常量 三.#define定义宏 3.1--定义宏的方法和注意事项 3.2--带有副作用的宏参数 3.3--宏替换的规则 四.宏与函数的对比 🔥个人主页:草莓熊Lotso的个人主页 🎬作者简介:C研发方向学习者 &a…

目录

一.预定义符号

 二.#define定义常量

三.#define定义宏

3.1--定义宏的方法和注意事项

3.2--带有副作用的宏参数

3.3--宏替换的规则

四.宏与函数的对比 


🔥个人主页:@草莓熊Lotso的个人主页

🎬作者简介:C++研发方向学习者

📖个人专栏:《C语言》

⭐️人生格言:生活是默默的坚持,毅力是永久的享受。


一.预定义符号

--C语言中设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。

1.  __FILE__ // 进行编译的源文件
2.  __LINE__ //文 件当前的行号
3.  __DATE__ //文 件被编译的日期
4.  __TIME__ //文 件被编译的时间
5.  __STDC__ // 如果编译器遵循 ANSI C ,其值为 1 ,否则未定义

--我们来使用一下这些预定义符号,观察它们打印出来的结果

#include<stdio.h>int main()
{printf("%s\n", __FILE__);printf("%d\n", __LINE__);printf("%s\n", __DATE__);printf("%s\n", __TIME__);return 0;
}


 二.#define定义常量

基本语法形式:

1.  #define name stuff

实际举例: 

1.  # define MAX 1000
2.  # define reg register // register 这个关键字,创建一个简短的名字
3.   # define do_forever for(;;) //用 更形象的符号来替换⼀种实现,这里是替换死循环
4.  # define CASE break;case // 在写 case 语句的时候自动把 break 写上。
  // 如果定义的 stuff 过长,可以分成几行写,除了最后⼀行外,每行的后面都加⼀个反斜杠 ( 续行 )
5.  # define DEBUG_PRINT printf( "file:%s\t  line:%d\t  date:%s\t  time:%s\n"   \
                                            ,__FILE__,
                                            __LINE__ , \
                                            __DATE__,\ 
                                             __TIME__ )

 我们看一下第4个和第5个的使用吧~

演示4:

#include<stdio.h>
#define CASE break;caseint main()
{int num = 0;scanf("%d", &num);switch (num){case 1:printf("hehe");//正常来说这里应该加break// 但是我定义了CASE为 break;caseCASE 2:printf("haha");//这里同理CASE 3:printf("呵呵");}return 0;
}

演示5: 

#include<stdio.h>
#define DEBUG_PRINT printf("file:%s\t line:%d\t date:%s\t time:%s\n" \,__FILE__, \__LINE__ , \__DATE__,   \__TIME__ )
int main()
{DEBUG_PRINT;return 0;
}

 

我们再来思考一个问题:在define定义标识符的时候,要不要在最后加上 ; 呢? 

比如:

  # define MAX 1000;
  # define MAX 1000

这当然是不行的,很容易导致一些问题,我们直接通过两个错误场景来直观的感受一下吧~

错误场景一:

#include<stdio.h>
#define MAX 1000;int main()
{printf("%d", MAX);//实际上会被解析为1000;;会出现两个分号return 0;
}

错误场景二:

#include<stdio.h>
#define MAX 1000;int main()
{int max = 0;int a = 3;int b = 4;if (a>b)max = MAX;elsemax = 0;return 0;
}

 

如果这里加了分号,等到替换之后,if和else之间实际上是两条语句,在没有大括号时,if后边只能控制一条语句。所以这里会出现语法错误。 


三.#define定义宏

3.1--定义宏的方法和注意事项

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

下面是宏的申明方式:

1.  #define name( parament-list ) stuff

其中的( parament-list )是一个由逗号隔开的符号表,它们可能出现在stuff中。

注意:

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

错误举例:

# define SQUARE( x ) x * x
这个宏接收⼀个参数 x .如果在上述声明之后,你把 SQUARE( 10 ); 置于程序中,预处理器就会⽤
下⾯这个表达式替换上⾯的表达式: 10  * 10。
但是这个代码存在一个问题,比如:
#include<stdio.h>
#define SQUARE(x) x*xint main()
{int a = 10;int r = SQUARE(a+1);printf("%d", r);return 0;
}

这个代码我们简单的来看很可能会认为结果是11*11=121,但其实并不是,它的实际结果是21。

 因为替换文本时,实际上是参数x被替换成a+1,所以这条语句应该被解析为:

int r  = a+1*a+1 ;//即为10+1*10+1=21;
printf ( "%d\n" ,r );

这样我们就可以清晰的看出替换后表达式所求的值了,那么我们该如何解决呢?

其实只需要在宏定义加上两个括号,这个问题就得以解决了

 #define SQUARE( x ) (x) * (x) 

这样改完后预处理完就可以得到你想要的结果了,变成了(10+1)*(10+1)。

但是呢,这样还不能完全解决所有问题,我们再来看看下面这个宏定义:

# define DOUBLE(x) (x) + (x)

这里我们可以看到定义中我们使用了括号,想避免之前出现的问题,但是这个宏可能会出现新的错误,我们来看如下代码:

#include<stdio.h>
#define DOUBLE(x) (x)+(x)int main()
{int a = 10;printf("%d", 5*DOUBLE(a));return 0;
}

这串代码打印出什么值呢?看上去好像很可能是100,但是实际上是60。

我们替换完可以发现:

printf ( "%d\n" ,5   * ( 10 ) + ( 10 ));

乘法的优先级先于宏定义后的加法,所有会出现60 ,这个问题我们只需要在宏定义表达式两边加上一对括号就可以了。

# define DOUBLE(x) ( ( x ) + ( x ) )

重要知识点:

所以⽤于对数值表达式进⾏求值的宏定义都应该⽤这种⽅式加上括号,所有地方都加上括号避免在使⽤宏时由于参数中的操作符和邻近操作符之间不可预料的相互作⽤。

3.2--带有副作用的宏参数

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

我们可以通过一个MAX宏来直观体会一下这个错误:

#include<stdio.h>
#define MAX(a,b) ((a)>(b)?(a):(b))int main()
{int x = 5;int y = 8;int z = MAX(x++, y++);printf("x=%d y=%d z=%d", x, y, z);return 0;
}

 我们来分析一下这串代码的结果会是什么吧

1. 先把z换成预处理之后的结果,即为z=( (x++) > (y++) ? (x++) : (y++));

2. 先看第一个表达式,后置加加,先比先x>y为假,所以表达式的结果会表达式3的结果,但是这里的x++后变成6,y++后变成9

3. 计算第三个表达式,此时y再++变成了10,但是因为是后置++所有在++之前把y之前为9的值赋给了z

所以x=6,y=10,z=9;

3.3--宏替换的规则

在程序中扩展#define定义符号和宏时,需要涉及⼏个步骤:
  1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先被替换。
  2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。
  3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上 述处理过程。

注意:

  1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
  2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

四.宏与函数的对比 

--宏通常被应用于执行简单的运算。

比如在两个数中我们想要找较大的一个数时,写成下面的宏的形式,更有优势一些

# define MAX(a, b) ((a)>(b)?(a):(b))
这里为什么用宏比函数更优呢?
原因如下:
  1. ⽤于调⽤函数和从函数返回的代码可能⽐实际执⾏这个⼩型计算⼯作所需要的时间更多。所以宏⽐ 函数在程序的规模和速度⽅⾯更胜⼀筹。
  2. 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使⽤。反之这个宏怎可以适⽤于整形、⻓整型、浮点型等可以⽤于 > 来⽐较的类型。宏的参数是类型⽆关的。

宏有时候可以做到一些函数做不到的事,比如:宏的参数可以出现类型,但是函数就做不到

# define MALLOC(num, type)\
(type )malloc(num sizeof(type))
...
// 使⽤
MALLOC( 10 , int ); // 类型作为参数
// 预处理器替换之后是:
( int * ) malloc ( 10 sizeof ( int ));

 但和函数相比宏也有它的劣势,如下:

  1. 每次使⽤宏的时候,⼀份宏定义的代码将插⼊到程序中。除⾮宏⽐较短,否则可能⼤幅度增加程序的⻓度。
  2. 宏是没法调试的。
  3. 宏由于类型⽆关,也就不够严谨。
  4. 宏可能会带来运算符优先级的问题,导致程容易出现错,(比如上面的自增++)

 宏和函数的对比关系表:

属性#define定义宏函数
代码长度每次使用时,宏代码都会被插入到程序中。除了非常小的宏以外,程序的长度都会被大幅增长函数代码只出现于一个地方;每次使用这函数时,都调用那个地方的同一份代码
执行速度更快存在函数的调用和返回的额外开销,所有相对慢一些
操作符优先级宏参数的求值是在周围所有表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议书写宏的时候多写括号函数参数只在函数调用的时候求值一次,其结果值传递给函数,表达式的求值结果容易预测
带有副作用的参数参数可能被替换到宏体中的多个位置,如果宏的参数被多次计算,带有副作用的参数求值可能会产生不可预料的结果。函数参数只在传参的时候求值一次,结果容易控制。
参数类型宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型函数的参数和函数类型有关,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是不同的。
调试宏是不方便调试的函数式可以逐语句调试的
递归宏是不能递归的函数是可以递归的

往期回顾:

【C语言编译与链接】--翻译环境和运行环境,预处理,编译,汇编,链接

【通关文件操作(上)】--文件的意义和概念,二进制文件和文本文件,文件的打开和关闭,文件的顺序读写

【通关文件操作(下)】--文件的顺序读写(续),sprintf和sscanf函数,文件的随机读写,文件缓冲区,更新文件

结语:本篇文章就到此结束了,继前面一篇文章后,在此篇文章中给大家分享了预处理详解中的部分知识点,如预定义符号,#define定义常量,#define定义宏,带有副作用的宏参数,宏替换的规则,宏和函数的对比等,下篇文章会接着为大家分享预处理详解的剩余知识点。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。

http://www.dtcms.com/wzjs/487438.html

相关文章:

  • 网站的运营方案网站seo优化外包
  • 淮南直聘网班级优化大师使用心得
  • 怎么在本机做网站搜索引擎优化排名
  • 石龙镇网站仿做百度最新秒收录方法2023
  • 怎么做网站赚钱的动漫网站搜索引擎营销的方法
  • 页面设计快捷键seo优化搜索推广
  • wordpress后台登陆地址修改seo职业发展
  • 网站被刷怎么办seo查询系统源码
  • 网络规划设计师教程第2版2021版pdf下载全面落实疫情防控优化措施
  • 布吉网站建设哪家公司靠谱提供seo顾问服务适合的对象是
  • 想建设一个网站关于网站推广
  • 网络营销的有哪些特点青岛seo计费
  • 黑龙江建设监理协会网站徐州做网站的公司
  • 网站建设 北京 淘宝百度推广代理查询
  • 长沙的网站建设公司搜索大全引擎
  • 网站网格设计百度推广客户端mac版
  • wordpress分类目录和标签的作用慈溪seo排名
  • 怎样创建自己的网站网站优化 秦皇岛
  • 网站开发后端是什么网页制作软件推荐
  • 宁波网站建设股份公司全球十大搜索引擎排名及网址
  • 公司企业网站开发百度seo建议
  • 上海做网站 公司 哪家好如何线上推广引流
  • 做模型的网站有哪些管理人员课程培训
  • 河南住房和城乡建设厅网站特种中国新闻最新消息
  • 哪个网站微博做的最好十大短视频平台排行榜
  • 台州网站建设 网站制作 网站设计搜索引擎营销实训报告
  • 400网站建设办公平台优化
  • c2c网站类型关键词优化排名软件哪家好
  • 线上运营推广工作内容seo技术优化服务
  • 网站建设无广告说到很多seo人员都转行了