预编译宏比较
⑴ 宏和函数的区别
1/ 宏只是预编译时一一展开,没有类型检查,可能产生二义性;同时宏写的函数不容易直观看懂。
#define MAX(a,b) ( (a)<(b)?(b):(a) )
2/ 内联函数并不总是被内联,inline对于编译器不是强制性的,缟译器根椐内联函数代码行数决定是否参于内联,从编译后生成的目标代码大小就能看出到底编译器是否真的内联了,调用1次和调用2次目标代码空间是不一样的。
template<typename T>
inline void Count( const T& a, const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
3/ 那么我们就强置内联好了,编译时会出现什么问题呢?
template<typename T>
inline __attribute__((always_inline)) void Count( const T& a,const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
Test.h:25: sorry, unimplemented: inlining failed in call to 'void Count(const T&, const T&) [with T = int]': function body not available
// 说明模板不能参于强制内联
4/ 去掉模板声明,采取强制内联是有效果的,并且随着调用次数的增加目标代码是不断增大的,说明强制内联起作用了,那它真达到宏的作用了吗?
inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
5/ 那我们改一下再和宏比较, 调用强制Count版本两次,没有报变量c被重复定义,不知道为什么? 难道可以获取到每一次调用Count的函数地址吗(实际GDB时就没有Count函数的概念)? 如果调用宏版本的Count,是会报变量c被重复定义,简单替换啦.
inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
#define Count(a,b) \
printf("always_inline?"); \
printf("always_inline?"); \
printf("always_inline?"); \
int c = a + b
⑵ 我想问一下C语言宏注释和/* //注释有什么区别
预编译与注释是不一样的概念。代码文本在进行编译时,首先排除了注释。然后根据预编译条件进行筛选排除或选择分支。就象宏,编译前首先替换宏,再进行编译。预编译和宏都是为了更高效率的代码编写和方便修改而存在的,不是为程序运行时准备的。
#if #endif 功能相当于if(){};只不过预编译是在代码编译前已经选择,条件选择是在运行时进行选择而已。
⑶ c++当中的预编译宏的问题
#ifndef HY //一般在头文件都都使用这种格式以防止头文件在同一文件中被包含两次。语名#ifndef hyong…..#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef….#endif之间的语句。
#define HY //在这里用define定义一个名字HY,以便在下次访问到该头文件时,使该名字已经被定义,从而让程序跳过#ifndef….#endif间的语句。
...
#endif
明白了??
如果还不明白,就下载本人的文章《C++名称空间与作用域专题》和《C++宏,预处理器,RTTI,typeid与强制类型转换》去了解了解吧。
⑷ C关于宏的计算
宏在预编译的时候处理,包含#的指令,都是在预编译的时候处理
相对于运行阶段,你也可以认为是编译阶段。
它只是简单的字符串替换,不是计算。
它不影响代码的执行速度,但是可能会增加代码的长度,影响最终生成的可执行文件的大小。
补充:
表达式(10/5)的计算,应该在运行的时候吧
无法通过编译选项控制这个的。
⑸ Source Insight,某些文件出现“parse too complex”,如何解决
你要的一次性从文件导入的功能类似的功能是有的,按照你之前选择的选项,
Options->Preferences->Languages->Project Specific Conditions
选择后再看右下角有个"Scan Files"按钮,这个是Source Insight尝试自己通过查找来确定所有预编译宏定义的数值(TRUE/FALSE),试了一下是好用的,但是具体能不能解决你的无法解析文件的问题不太确定。
如果还不能解决的话,最好针对这些个别文件注意一下在函数中的if等判断条件内部和括号处试用了预编译指令导致Source Insight无法识别的情况。重新将这些预编译指令调整到括号的外面有时就能解决,我遇到你这种情况就是是这样解决的。
⑹ C++,宏定义怎么用
宏定义又称为宏代换、宏替换,简称"宏"。
格式:
#define 标识符 字符串
其中的标识符就是所谓的符号常量,也称为"宏名"。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握"宏"概念的关键是"换"。一切以换为前提、做任何事情之前先要换,准确理解之前就要"换"。
即在对相关命令或语句的含义和功能作具体分析之前就要换:
例:
#define Pi 3.1415926
把程序中出现的Pi全部换成3.1415926
⑺ 宏、函数、宏函数的区别
宏、函数、宏函数的区别
先说宏和函数的区别:
1. 宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类型的,可以是各种各样的类型.
2. 宏的参数替换是不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的.
3. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.
4. 宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.
5. 函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,
这些操作,显然在宏中是没有的.
现在来看内联函数:
所谓"内联函数"就是将很简单的函数"内嵌"到调用他的程序代码中,只样做的目的是为了避免上面说到的第5点,目的旨在节约下原本函数调用时的时空开销.但必须注意的是:作为内联函数,函数体必须十分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。
函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要一些CPU时间。
而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。
1. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.
这句分开解释:
"" 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,""
解释:假设代码中有这么一条宏定义:#define MAX_LEN 10(10是宏体, MAX_LEN 是宏名)则在编译之前, 也就是在预编译的时候会将代码中所有出现MAX_LEN的地方替换成10后在进行下面的代码编译, 这种替换工作实在编译之前进行的...
"" 而函数显然是编译之后,在执行时,才调用的""
解释: 函数调用实在执行时才调用的这是显然的, 因为只有执行时才能根据具体的条件决定调用哪个函数
""因此,宏占用的是编译的时间,而函数占用的是执行时的时间. ""
解释:有了上面的解释,估计这句话也就知道了, 从他的这句话看书的作者把预编译也算作编译的一部分了...
2.宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.
同样分开解释:
"" 宏的参数是不占内存空间的,因为只是做字符串的替换""
解释:假设有这么个宏定义#define MAX(a, b) (a) > (b) ? (a) : (b) 代码中所有出现(初定义外)MAX(a, b)的地方在预编译以后都变成了 (a) > (b) ? (a) : (b)这个式子, 比如代码中有c = MAX(1, 3)这样的语句, 则在预编译的时候就会变成c = (1) > (3) ? (1) : (3), 这是一种直接的替换, 不会产生中间变量, 所以也就不用为之分配空间 ...
"而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的."
解释: 函数调用时需要为每个形式参数在栈上分配空间, 然后将实参的值拷贝进去, 在函数的内部用的都是这个形参, 当函数结束后形参的空间会被自动释放掉, 这也是为什么形参的改变无法改变实参的值的原因...
==================================================
宏: 内联函数:
1.由预处理器处理 1.编译器处理
2.对++/--操作有副作用 2.可能会被编译器拒绝(不一定内联)
3.难于调试 3.可能造成代码膨胀
4.必定被展开
******************************************************************************************************
宏函数和函数的使用小结:
函数体量很小时,为了减小系统的开销时间,可以使用宏函数,而函数体比较复杂(需要递归、循环、判断、选择等...)的情况下,使用函数来定义可以避免宏函数定义带来的副作用。 宏函数是在程序编译时进行简单的字符替换,而函数是在程序生成后才进行调用,这时会占用开销时间(主程序函数保留现场,在子函数体中需要进行参数的传递--实参传递给形参以及调用完后形参的销毁等步骤 ),因此宏函数占用的编译时的时间,而函数占用的是执行时的时间。 因此在函数体量简单的情况下,使用宏函数可以极大的提高程序的执行效率和系统开销。
⑻ C++#if宏比较
可以比较,不过这样写代码的可读性不是很好
你可以这样变通一下
#defineCONDITION_XXX(A==B)
#ifCONDITION_XXX
...
⑼ 宏和函数的区别是什么
1/ 宏只是预编译时一一展开,没有类型检查,可能产生二义性;同时宏写的函数不容易直观看懂。
#define MAX(a,b) ( (a)<(b)?(b):(a) )
2/ 内联函数并不总是被内联,inline对于编译器不是强制性的,缟译器根椐内联函数代码行数决定是否参于内联,从编译后生成的目标代码大小就能看出到底编译器是否真的内联了,调用1次和调用2次目标代码空间是不一样的。
template<typename T>
inline void Count( const T& a, const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
3/ 那么我们就强置内联好了,编译时会出现什么问题呢?
template<typename T>
inline __attribute__((always_inline)) void Count( const T& a,const T& b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
Test.h:25: sorry, unimplemented: inlining failed in call to 'void Count(const T&, const T&) [with T = int]': function body not available
// 说明模板不能参于强制内联
4/ 去掉模板声明,采取强制内联是有效果的,并且随着调用次数的增加目标代码是不断增大的,说明强制内联起作用了,那它真达到宏的作用了吗?
inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
5/ 那我们改一下再和宏比较, 调用强制Count版本两次,没有报变量c被重复定义,不知道为什么? 难道可以获取到每一次调用Count的函数地址吗(实际GDB时就没有Count函数的概念)? 如果调用宏版本的Count,是会报变量c被重复定义,简单替换啦.
inline __attribute__((always_inline)) void Count( int a,int b )
{
printf("always_inline?");
printf("always_inline?");
printf("always_inline?");
int c = a + b;
}
#define Count(a,b) \
printf("always_inline?"); \
printf("always_inline?"); \
printf("always_inline?"); \
int c = a + b
⑽ C语言如何在预编译阶段比较字符串
#define dprint(expr) printf(#expr"=%d",expr)
int i=j=1;
dprint(i+j);//展开后为 printf("i+j""=%d",expr);