C 全局访问和指针访问之间的差异

C 全局访问和指针访问之间的差异,c,pointers,embedded,C,Pointers,Embedded,想知道以下两位标记为方法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 *

想知道以下两位标记为方法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;
 }
如上所述,最佳做法的优点/缺点是什么

谢谢

方法3:

void SomeFunction(int myInt, s_Thing* pWho)
{
    pWho->iAnInteger = 0;
}
更好,因为如果您更改s_Thing实例的创建方式,它将更易于维护


另外两种方法都存在本地化问题:尝试限制修改全局范围内数据的函数数量

方法1和方法2基本上做相同的事情,方法1只是增加了一个额外的间接层次,没有真正的原因或好处

这两种方法都会修改全局对象的内容,从而导致紧张和问题

正确的做法是SomeFunction将s_对象作为可写参数:

void SomeFunction( int myInt, s_Thing *myThing )
{
  ...
  myThing->iAnInteger = 0;
  ...
}
这会被称为

int main( void )
{
  s_Thing sMine;
  ...
  SomeFunction( anInt, &sMine );
  ...
}
通常,函数应该通过参数和返回值进行通信,而不是通过设置全局值。有时会使用全局is
必要的,如与,但生活将更容易,如果你能避免它

除了可读性之外,没有区别

考虑一下:如果你有一个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;
它的可读性更高,篇幅更短,特别是如果您必须对同一个结构执行许多重复操作的话


就剩下的部分而言,现在的大多数编译器应该为这两种方法生成相同的代码。

挑剔:变量名中是否有必要包含一个整数?类型已经对知识进行了编码,这使得它有点多余。如果类型改变,你会记得更改名称以防止误导他人吗?我不知道你在这个问题上的意思是什么;在这两种情况下仍然有一个全局对象。谢谢。是的,认识到在这两种情况下都有一个全球性的问题。对于这样的东西,是否有一个一致的最佳实践?一个全局结构。byxor,变量名只是我目前缺乏创造力,问题主要集中在指针和全局上。它们是做同一件坏事的不同方式。通过一个本地指针访问一个全局对象,既不能防止全局对象的危害,也没有任何好处。关于全球化以及如何避免全球化的建议,请阅读Jack Ganssle的。你这里的本地化是什么意思?我还是不明白这个词,虽然我完全同意你的风格技巧,但这种方法似乎很合乎逻辑。在缺少主操作系统(即RTO)的情况下,过去在哪里定义sMine?@1point8zero61:这完全取决于应用程序的功能。sMine实例需要存活多长时间?sMine在整个程序中存活。它包含所有相关的硬件细节。它被许多任务访问。我喜欢您建议在main中定义的想法,但显然,这不是一个选项。@1point8zero61在它所属的模块中声明它。在嵌入式系统上,在文件范围内声明变量是完全正确的,只要它们声明为静态的。这会阻止从任何地方访问它们-只有它们所在的文件才能访问它们。尽管如此,我们还是要注意重新进入市场的问题。@Lundin谢谢。这是否意味着文件级别的“全局”实际上是可接受的做法?这基本上就是我所拥有的。名为time.c的文件,具有从不同模块中的SW时钟访问的get/set函数。当运行“set”时,它会按照我的原始代码片段中所示的方式递增。