想知道以下两位(标记为方法1和方法2)之间的差异是什么,与之相关的任何利益/风险,最后是否有更好的方法。
typedef struct
{
int iAnInteger;
} s_Thing;
s_Thing sMine;
void SomeFunction(int myInt)
{
/* Method 1 */
s_Thing *pMine = &sMine;
pMine->iAnInteger = 0;
/* Method 2 */
sMine.iAnInteger = 0;
}
如上所述,有哪些优点/缺点,最佳做法?
谢谢!
答案 0 :(得分:5)
方法3:
void SomeFunction(int myInt, s_Thing* pWho)
{
pWho->iAnInteger = 0;
}
甚至更好,因为如果您对s_Thing
的实例的创建方式进行更改,则更易于维护。
您的其他两种方法都存在本地化问题:尝试限制修改全局范围内的数据的函数数量。
答案 1 :(得分:0)
方法1和方法2基本上做同样的事情,方法1只是增加了一个额外的间接层,没有真正的理由或好处。
这两种方法都会修改全局对象的内容,从而导致紧coupling , re-entrancy 和 thread safety 问题。
正确的要做的事情是SomeFunction
将s_Thing
作为可写参数:
void SomeFunction( int myInt, s_Thing *myThing )
{
...
myThing->iAnInteger = 0;
...
}
会被称为
之类的东西int main( void )
{
s_Thing sMine;
...
SomeFunction( anInt, &sMine );
...
}
通常,函数应通过参数和返回值进行通信,而不是通过设置全局变量。使用global时,是次
必要的(例如errno
),但如果你能避免它,生活会更容易。
答案 2 :(得分:0)
除了可读性之外没有区别。
考虑一下:如果你有struct,它有一个struct作为它的一个成员,而struct又有一个struct作为它的一个成员,反过来......好吧,你明白了。
然后,如果您需要将值A
与内部结构的值B
进行比较,您最终会得到像
Struct1.Struct2.Struct3.Struct4.Struct5.A == Struct1.Struct2.Struct3.Struct4.Struct5.B
或者,你可以把
MY_STRUCT* pMeaningfulName = &Struct1.Struct2.Struct3.Struct4.Struct5;
pMeaningfulName.A == pMeaningfulName.B;
更具可读性和更短,特别是如果你必须使用相同的结构进行许多重复操作。
就其他方面而言,现在大多数编译器应该为这两种方法生成相同的代码。