标题:[讨论]FAQ新增条目建议 内联函数有关知识
只看楼主
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
 问题点数:0 回复次数:19 
[讨论]FAQ新增条目建议 内联函数有关知识

[9.1] 内联函数是干嘛的?
内联函数是将被插入到调用者代码流中的函数,就像一个#define的宏一样,内联函数通过避免调用自己和(特别是)通过编译在调用过程中优化调用过程(过程整合)来达到提升性能的效果.

[9.2] 内联函数是如果保证安全和速度的平衡性的?
在C中,你可以通过在结构体里面放置一个void*来达到"封装的结构体",这种情况下,void*指向结构体中用户不知道的实际数据。这样结构体的用户就不知道如何解释用void*指向的内容,但是访问这些函数的时候就会从void*型自动转换为相应的合适的类型。这就给出了一种形式的封装。

不幸的是它失去了类型的安全性,它也在强制函数调用的时候要访问结构体中每个角落的数据(如果你允许对结构体进行直接的访问的话,任何人都可以访问它们,因为他们有必要知道他们如何解析用void*指向的东西,这个会让改变数据结构的时候变得更加困难了.

C++类允许函数调用扩展内联.这就可以让你安全地进行封装,而且保证了快速的直接的访问.此外,这些内联函数的参数类型是由编译器来进行检查的,这是对于C中的#define宏的一个改进.

[9.3] 我为什么要用内联函数呢?而不是用原来好好的#define宏?

因为#define宏在四个方面是非常糟糕的(这里的内容没有找到,比较遗憾)

不像#define宏,内联函数可以避免声名狼籍的宏错误因为内联函数总是对每个参数精确匹配一次。换言之,调用内联函数在语义上只是像调用了一个正则表达式,只是要更快一些:

//一个返回i绝对值的宏
#define unsafe(i) ( (i) >=0 ? (i) : -(i) )

//一个返回i的绝对值的内联函数
inline int safe(int i)
{
return i>=0?i:-i;
}

int f();

void userCode(int x)
{
int ans;

ans=unsafe(x++);
ans=unsafe(f());

ans=safe(x++);
ans=safe(f());
}


与宏不一样的是,参数的类型是会被检查的,不必要的会话会被正确的处理。

宏对你的程序的健康是不利的,除非不得以,否则不要用它们!

[9.4] 你怎么让编译器识别一个非成员函数的内联函数?
当你申明一个内联函数的时候,它看起来就像是一个普通的函数:
void f(int i,char c)
但是当你定义一个内联的函数,你把函数的定义加上inline关键字,当你所以下的定义放入头文件之后:

inline
void f(int i,char c)
{
//...
}
注意:把一个函数的定义放到一个头文件里面是一个规则性的东西。除非函数只是在一个单独的cpp文件中调用到了。特别的,如果你把内联函数放在一个cpp文件里面,而你从其他的cpp文件里面调用它,你会在连接器得到一个"unresolved external"错误。

[9.5] 你怎么让编译器识别一个内联的成员函数?
当你定义一个成员函数的时候,它看起来就像是一个普通的成员函数:

class Fred {
public:
void f(int i,char c);
};

但是如果你定义一个内联的成员函数的时候,你就得在函数定义前使用inline关键字,并且把这个定义放到一个头文件中,
inlune
void Fred::f(int i,char c)
{
//...
}

注意:把一个函数的定义放到一个头文件里面是一个规则性的东西。除非函数只是在一个单独的cpp文件中调用到了。特别的,如果你把内联函数放在一个cpp文件里面,而你从其他的cpp文件里面调用它,你会在连接器得到一个"unresolved external"错误。

[9.6] 是不是有另外一种方法让编译器识别到一个内联的成员函数?
是的!在类体内定义一个成员函数的时候就相当于把它申明为一个内联函数:

class Fred {
public:
void f(int i,char c)
{
//...
}
};

尽管这对于写这个类的人来说更加简单一些,但是这个对于所有的阅读者来说就变得更加困难了,因为它混了什么是一个类与这个类怎么实现它两个问题。因为这个混淆的存在,我们通常用inline关键字在类的外面定义成员函数。这个认识就有以下的意义了:在一个面向代码重用的世界里,有很多人会使用你的类,但是只有一个人来编写它(你自己),这样你就应该做一些能让更多的人受益的事,而不让极少数人受益.

[9.7] 内联函数会一定让你的程序性能更好吗?
不是的。

注意内联函数的过度应用会造成代码的膨肿,这个会让分页平台环境的性能降低。

[此贴子已经被百年不亮于2007-9-21 23:08:19编辑过]

搜索更多相关主题的帖子: FAQ 内联 条目 函数 知识 
2007-09-21 19:55
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 
我们的讨论话题限定在C中,C++中的概念涉及越少越好。
栖柏兄再修改下。

这里不用讲的太详细。只需说清什么是inline,为什么要用inline ,inline和宏函数比有什么优势就行了。

=======================================================================================================
讨论C中inline的文章很少,可以参考一些C++的:
http://dev.yesky.com/260/2095260.shtml

注意FAQ中不要引入C++中的概念。
2007-09-21 20:39
sunyuantz
Rank: 1
等 级:新手上路
威 望:1
帖 子:407
专家分:0
注 册:2006-3-20
得分:0 
不错,学习了。不过对于刚刚学习C的人来讲还是太深啊!内联涉及到程序的性能问题,新手认为能写出并解决问题就行了,等他们学习了更深的知识后,就会开始关注到他们程序的执行效率问题!

我不是名人,所以不要签名。等哪天我成名人了......你都认识我了还要签名干嘛!
2007-09-21 20:40
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
得分:0 
不是说c99有inline了么?
我不知道,不知道怎么修改呢?你修改吧

You have lots more to work on! Never give up!c language!
2007-09-21 20:42
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 

我不知道,不知道怎么修改呢?你修改吧


你既然已经提出了这个问题,当然是由你完成了,查查资料,baidu一下就OK了

都让我做还不累死我
2007-09-21 20:45
coachard
Rank: 3Rank: 3
等 级:新手上路
威 望:7
帖 子:1251
专家分:0
注 册:2007-8-12
得分:0 
这篇文章只好像没涉及到OOP,所以要把C++,CPP之类的字眼删掉就行了。。。

偶学编程,也许本身就是一个错。。。
2007-09-21 20:50
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
得分:0 
好的见解,也没必要,我想学了c++,c也会了

You have lots more to work on! Never give up!c language!
2007-09-21 20:51
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 
栖柏兄看看我2楼的回复,这个FAQ是给学习C的初学者看的,所以不要出现C++中有而C中没有的概念。新手看C的FAQ看到一个class是不是会很郁闷?

赶紧动手改吧。
2007-09-21 20:56
coachard
Rank: 3Rank: 3
等 级:新手上路
威 望:7
帖 子:1251
专家分:0
注 册:2007-8-12
得分:0 

不知班竹何时能把FAQ整理成册???


偶学编程,也许本身就是一个错。。。
2007-09-21 20:58
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
得分:0 
不知班竹何时能把FAQ整理成册???


我当然希望越早越好,不过得有人帮忙才快呀!
2007-09-21 20:59



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-171912-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.156880 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved