成都网站建设选择到访率,58同城合肥网站建设,龙凤网站建设云聚达,做公司网站的目的是什么主页#xff1a;114514的代码大冒 qq:2188956112#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ #xff09; Gitee#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录
文章目录
前言 2.5带副作用的宏参数
2.6宏和函数的对比
3#undef
编辑
4 命令行定义… 主页114514的代码大冒 qq:2188956112欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ Gitee庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录
文章目录
前言 2.5带副作用的宏参数
2.6宏和函数的对比
3#undef
编辑
4 命令行定义
5 条件编译
6 文件包含
总结 前言
咱们书接上回 2.5带副作用的宏参数
先来看一段代码
#define MAX(x,y) ((x)(y)?(x):(y))int main()
{int a 4;int b 6;int m MAX(a, b);printf(%d\n, m); printf(a%d b%d\n, a, b);return 0;
}
这个结果是什么呢 为什么
我们一样要考上文中的“宏是一种替换”的概念先做一下替换然后我们来解析一下 当宏参数在宏的定义中出现超过一次的时候如果参数带有副作用那么你在使用这个宏的时候就可能出现危险导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 x1;//不带副作用
x;//带有副作用
但是在这里这种情况函数就不会发生类似问题
这里我提供了测试代码读者可自取 #define MAX(x,y) ((x)(y)?(x):(y))int Max(int x, int y)
{return x y ? x : y;}int main()
{//int m MAX(2, 3);//printf(%d\n, m);int a 4;int b 6;int m MAX(a, b);//int m Max(a, b);printf(%d\n, m); // m 7printf(a%d b%d\n, a, b);return 0;
}
2.6宏和函数的对比
函数的反汇编 宏的反汇编 宏明显要快不少嘛
宏通常被应用于执行简单的运算。 比如在两个数中找出较大的一个。宏的优点1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。 所以宏比函数在程序的规模和速度方面更胜一筹。 2. 更为重要的是函数的参数必须声明为特定的类型。 所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于来比较的类型。 宏是类型无关的。 宏的缺点 当然和函数相比宏也有劣势的地方 1. 每次使用宏的时候一份宏定义的代码将插入到程序中。除非宏比较短否则可能大幅度增加程序的长度。 2. 宏是没法调试的。 3. 宏由于类型无关也就不够严谨。 4. 宏可能会带来运算符优先级的问题导致程容易出现错。 宏没有类型如上图所示函数只能进行固定类型数据的操作而宏却可以忽视这一细节
但是对应的宏是一种替换也就是说他会把定义的内容替换到正文代码中造成代码超度变长
另外就是像上文所说的那种“副作用”足以看出宏在调试时的问题是比较大的
因为“你看到的并非你看到的宏替换的关系”
所以总的说来宏有着优点也有着缺点
具体使用函数还是宏要根据实际情况 属 性 #define定义宏 函数 代 码 长 度 每次使用时宏代码都会被插入到程序中。除了非常 小的宏之外程序的长度会大幅度增长 函数代码只出现于一个地方每 次使用这个函数时都调用那个 地方的同一份代码 执 行 速 度 更快 存在函数的调用和返回的额外开 销所以相对慢一些 操 作 符 优 先 级 宏参数的求值是在所有周围表达式的上下文环境里 除非加上括号否则邻近操作符的优先级可能会产生 不可预料的后果所以建议宏在书写的时候多些括 号。 函数参数只在函数调用的时候求 值一次它的结果值传递给函 数。表达式的求值结果更容易预测 带 有 副 作 用 的 参 数 参数可能被替换到宏体中的多个位置所以带有副作 用的参数求值可能会产生不可预料 的结果 函数参数只在传参的时候求值一次结果更容易控制。 参 数 类 型 宏的参数与类型无关只要对参数的操作是合法的 它就可以使用于任何参数类型。 函数的参数是与类型有关的如果参数的类型不同就需要不同的函数即使他们执行的任务是相同的。 调 试 宏是不方便调试的 函数是可以逐语句调试的 递 归 宏是不能递归的 函数是可以递归的 2.7 命名约定 一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。 那我们平时的一个习惯是 把宏名全部大写 函数名不要全部大写 3#undef
这条指令用于移除一个宏定义。 #undef NAME //如果现存的一个名字需要被重新定义那么它的旧名字首先要被移除。 4 命令行定义
许多C 的编译器提供了一种能力允许在命令行中定义符号。用于启动编译过程。 例如当我们根据同一个源文件要编译出一个程序的不同版本的时候这个特性有点用处。假定某个程序中声明了一个某个长度的数组如果机器内存有限我们需要一个很小的数组但是另外一个机器内存大些我们需要一个数组能够大些。#include stdio.h
int main()
{int array [ARRAY_SIZE];int i 0;for(i 0; i ARRAY_SIZE; i ){array[i] i;}for(i 0; i ARRAY_SIZE; i ){printf(%d ,array[i]);}printf(\n );return 0;
} 编译指令 //linux 环境演示
gcc -D ARRAY_SIZE10 programe.c 5 条件编译 在编译一个程序的时候我们如果要将一条语句一组语句编译或者放弃是很方便的。因为我们有条件编译指令。 比如说
调试性的代码删除可惜保留又碍事所以我们可以选择性的编译------------------------------条件编译的“条件”不可以是变量------------------------------------------------
因为条件编译中的条件在预处理阶段就已经处理了而预处理阶段不处理变量 使用方法再举例 关系可以向C语言中的“if.....else”语句考虑
更多例子 6 文件包含 这个多次包含编译器是不会进行报错的但是这个东西意味着程序将多次调用同一段代码
这显然是多余的ok看起来似乎这个多次包含同一文件的错误对于个人来讲很容易规避
但是如果是 下图这般 如何避免呢
答条件编译 下面这个放在第一行也具有相同作用
#pragma once//这个也是OK的#include filename.h 和 #include filename.h有什么区别? 答如果使用尖括号那么程序将直接在系统头文件库寻找该文件
如果使用引号那么程序将现在本地找一找找不到才回去系统头文件库查找
从提升效率的角度讲系统头文件调用时应该使用
而个人创建的头文件应该使用“” 总结
提示这里对文章进行总结 例如以上就是今天要讲的内容本文仅仅简单介绍了pandas的使用而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。