宏定义,条件编译以及函数指针
2016-04-23 17:47
281 查看
一:宏定义:
1:宏定义是一种有效的避免幻数的方法。
比如函数调试的时候,我们需要在特定行输出调试信息,如exit(1);这里的“1”就是幻数,我们可以这样
#define NUMBER_ERROR 1
这样就是直接能让我知道,错误是number_error引起的。杜绝幻数,方便调 试。
2:用宏函数来代替某些简短而频繁使用的函数。
比如我们可以用#define MAX(a,b) (a) > (b) ? (a) : (b) 来代替下面这个小函数:
int max (int a,int b)
{
return a > b ? a : b;
} //比较a和b的大小,a大于b选a,a小于b选b
那么这样做有什么好处呢?
其实这是一个经典的以时间换空间的例子,我们牺牲了编译器的编译时间来换取内存,因为没有了函数的调 用,给形参分配空间等过程。
3:内敛函数。
我们上面说宏函数是经典的以时间换空间的例子,那么有没有以空间换时间的存在呢?
答案是肯定的!
这就要提到我们的标题了——内敛函数。
我们首先说到了时间的概念,时间是分为两种的,一种是编译时间,一种是执行时间。
我们所能做的就是通过内敛函数来换取执行时间。请看下面内敛函数的定义:
inline int max (int a,int b)
{
return a > b ? a : b;
}
在函数的定义前面加上inline就是内敛函数了。当调用这个函数的时候,并没有传参这个过程,而是直接 把函数体语句搬到调用点。
这就是我们说的以空间来换时间。
4:内置宏。
在C语言中是有很多的内置宏的,比如:
__LINE__这是行号的内置宏
__func__这是所在函数名的内置宏
两者一起使用的话,可以构成一个调试信息。比如:
printf("%s%d",__func__,__LINE__);//打印所在函数名和行号
我们在某些我们需要的地方下面加上上面的调试信息,就可以知道错误出现在那个函数的哪一行。
静待补充
二:条件编译。
1:条件编译在主函数用到的时候是作为调试信息的。比如:
#ifndef max
printf("error\n");
else
printf("perfect\n");
#endif
上面就是一个条件编译的基本格式以及基本用法,合理的运用条件编译可以为我们程序的后期调试带来很大 的方便。
2:头文件中的条件编译。
如果我们写了一个.h头文件a,又写了另一个.h头文件b,在b中我们声明了#include "a.h",然后我们在主函数 里又声明了:
#include "a.h"
#include "b.h"
你编译的时候就会发现,编译器报了一个a的重复定义错误,那怎样避免呢,如下所示:
#ifndef A_H
#define A_H
这里是a头文件内容
#endif
我们毎写一个头文件的时候,都加上这三行代码,就可以解决头文件重复包含所带来的重复定义问题。
我们需要养成这样的习惯,这也是一种良好的编码规范。
静待补充
三:函数指针。
指针函数,顾名思义就是指向函数的指针。
其实,我们毎写一个函数,编译器就会将函数名默认转化为函数指针。函数指针的定义如下:
void (*p)(int)
这样我们就定义了一个整形的函数指针了。函数指针主要的作用是作为回调函数来使用的,也就是一函数 指针为形参。
这样做有什么好处呢?<
4000
/strong>
[b] 比如我写了这样的函数:
max(p,a)
我们在主函数调用的时候,p的位置可以传任何符合p数据类型的函数,也就是说我们传参的选择变得多样 化了 。
本人对函数指针的理解还有很多不足,希望大家多提宝贵意见,后期会有补充。
1:宏定义是一种有效的避免幻数的方法。
比如函数调试的时候,我们需要在特定行输出调试信息,如exit(1);这里的“1”就是幻数,我们可以这样
#define NUMBER_ERROR 1
这样就是直接能让我知道,错误是number_error引起的。杜绝幻数,方便调 试。
2:用宏函数来代替某些简短而频繁使用的函数。
比如我们可以用#define MAX(a,b) (a) > (b) ? (a) : (b) 来代替下面这个小函数:
int max (int a,int b)
{
return a > b ? a : b;
} //比较a和b的大小,a大于b选a,a小于b选b
那么这样做有什么好处呢?
其实这是一个经典的以时间换空间的例子,我们牺牲了编译器的编译时间来换取内存,因为没有了函数的调 用,给形参分配空间等过程。
3:内敛函数。
我们上面说宏函数是经典的以时间换空间的例子,那么有没有以空间换时间的存在呢?
答案是肯定的!
这就要提到我们的标题了——内敛函数。
我们首先说到了时间的概念,时间是分为两种的,一种是编译时间,一种是执行时间。
我们所能做的就是通过内敛函数来换取执行时间。请看下面内敛函数的定义:
inline int max (int a,int b)
{
return a > b ? a : b;
}
在函数的定义前面加上inline就是内敛函数了。当调用这个函数的时候,并没有传参这个过程,而是直接 把函数体语句搬到调用点。
这就是我们说的以空间来换时间。
4:内置宏。
在C语言中是有很多的内置宏的,比如:
__LINE__这是行号的内置宏
__func__这是所在函数名的内置宏
两者一起使用的话,可以构成一个调试信息。比如:
printf("%s%d",__func__,__LINE__);//打印所在函数名和行号
我们在某些我们需要的地方下面加上上面的调试信息,就可以知道错误出现在那个函数的哪一行。
静待补充
二:条件编译。
1:条件编译在主函数用到的时候是作为调试信息的。比如:
#ifndef max
printf("error\n");
else
printf("perfect\n");
#endif
上面就是一个条件编译的基本格式以及基本用法,合理的运用条件编译可以为我们程序的后期调试带来很大 的方便。
2:头文件中的条件编译。
如果我们写了一个.h头文件a,又写了另一个.h头文件b,在b中我们声明了#include "a.h",然后我们在主函数 里又声明了:
#include "a.h"
#include "b.h"
你编译的时候就会发现,编译器报了一个a的重复定义错误,那怎样避免呢,如下所示:
#ifndef A_H
#define A_H
这里是a头文件内容
#endif
我们毎写一个头文件的时候,都加上这三行代码,就可以解决头文件重复包含所带来的重复定义问题。
我们需要养成这样的习惯,这也是一种良好的编码规范。
静待补充
三:函数指针。
指针函数,顾名思义就是指向函数的指针。
其实,我们毎写一个函数,编译器就会将函数名默认转化为函数指针。函数指针的定义如下:
void (*p)(int)
这样我们就定义了一个整形的函数指针了。函数指针主要的作用是作为回调函数来使用的,也就是一函数 指针为形参。
这样做有什么好处呢?<
4000
/strong>
[b] 比如我写了这样的函数:
max(p,a)
我们在主函数调用的时候,p的位置可以传任何符合p数据类型的函数,也就是说我们传参的选择变得多样 化了 。
本人对函数指针的理解还有很多不足,希望大家多提宝贵意见,后期会有补充。
相关文章推荐
- C#.NET学习笔记5 C#中的条件编译
- C语言中的函数指针基础学习教程
- C++编程中的函数指针初步解析
- C/C++ 宏详细解析
- 深入解析C语言中函数指针的定义与使用
- C语言中的函数指针学习笔记
- 实例解析C++中类的成员函数指针
- 简单记录C# 条件编译
- C++普通函数指针与成员函数指针实例解析
- 浅谈内联函数与宏定义的区别详解
- C语言中的内联函数(inline)与宏定义(#define)详细解析
- 基于C中含有if的宏定义详解
- 深入探讨:宏、内联函数与普通函数的区别
- C++十六进制宏的用法详解
- C++基础入门教程(九):函数指针之回调
- C++基础入门教程(二):数据、变量、宏等
- C语言中函数与指针的应用总结
- 枚举和宏的区别详细解析
- 内联函数inline与宏定义深入解析
- 简明的C++函数指针学习教程