C代码:为什么有人要声明一个变量和一个指针,然后将指针指向该变量的地址?

C代码:为什么有人要声明一个变量和一个指针,然后将指针指向该变量的地址?,c,pointers,C,Pointers,我有一些30年的C代码,我正试图清理,我遇到了一些我不知道我是否应该改变的东西。代码如下所示: MY_OBJ obj1; MY_OBJ *obj2; int main(int argc, char *argv[]){ obj2 = &obj1; ... } 然后再也不会引用obj1。有什么理由在C中这样做吗?我并不完全是新手,但一些内存管理对我来说还是新鲜的,我不想把任何事情搞砸。如果我重写它,然后直接声明obj2如下,会是一样的吗 MY_OBJ obj2; int

我有一些30年的C代码,我正试图清理,我遇到了一些我不知道我是否应该改变的东西。代码如下所示:

MY_OBJ obj1;
MY_OBJ *obj2;

int main(int argc, char *argv[]){
    obj2 = &obj1;
    ...
}
然后再也不会引用
obj1
。有什么理由在C中这样做吗?我并不完全是新手,但一些内存管理对我来说还是新鲜的,我不想把任何事情搞砸。如果我重写它,然后直接声明
obj2
如下,会是一样的吗

MY_OBJ obj2;

int main(int argc, char *argv[]){
    ...
}

谢谢

您的替代品不一样
obj1
是一个已分配的对象,它可能很大,比如100或1000字节。但是
obj2
只是一个指针,在许多典型的平台上,它占用4个字节

在许多程序中,传递一个指针是很有用的,并且可能会为另一个对象(如
obj1
)更新其值,而不必复制大量内存。为了安全起见,
obj1
可能是一个默认值,文件或网络事务提供了一个更有意义的值

简言之,给定的代码肯定是有道理的。而且它也可能过时,这取决于项目的历史

为什么有人要声明一个变量和一个指针,然后将指针指向该变量的地址

因为他们想要一个对象,他们想要一个指向该对象的指针

我们无法告诉您他们是否有充分的理由需要指向该对象的指针,因为您还没有演示如何使用指针。我肯定能想出这样做的好理由,但我无法猜测他们是否适用于这里

我并不完全是新手,但一些内存管理对我来说还是新鲜的

你懂指针吗

如果不是,你在所有意图和目的上都是“全新的”。指针操作在惯用C语言中非常常见

您了解这个指针在以后的代码中是如何使用的吗?如果不是,你绝对不应该改变它。理解代码现在所做的是重构的最低先决条件

如果我重写它并直接声明obj2,它会是一样的吗


这是我担心你不理解指针的原因之一。指向对象的指针与对象不同。由于您没有向我们展示指针在以后如何使用,我们无法告诉您,只要稍作语法更改,这基本上是可以的,还是完全不可行。

传递指针不仅因为更小而更便宜,而且是让函数修改指向结构的唯一方法,因为所有参数都是通过C中的值传递的(即复制的)。更改obj1的唯一其他方法是将其作为全局变量引用,而直接从函数中引用全局变量是一个坏主意

要注意的第二件事是指针必须指向某个有用的东西:它可以是静态分配的长寿命全局变量,也可以是通过在程序中的某个点调用
malloc
创建的动态分配变量。第一种方法对于长寿命的变量更有意义,但如果您想摆脱
obj1
,这也可以:

// must remember to free this memory at some point
obj2 = malloc(sizeof *obj2);
由于指针也是全局的,这看起来像是一次初始化,因此在其声明点对其进行初始化并将其标记为const将更有意义:

MY_OBJ obj1;

// Initialize obj2 to &obj1 and mark it const so
// that it cannot point to anything else
// (this still allows you to dereference it 
// and modify the contents of the pointed struct)
MY_OBJ * const obj2 = &obj1;

最后,请注意,传递
&obj1
而不是
obj2
也可以正常工作。

应该有一些函数将
MY_OBJ*
作为参数。如果您删除
obj2
,您还应该编写
&obj1
,而不是所有的
obj2
s。

我通常这样做
MY_OBJ OBJ[1]/*={0}*/
获取一个/*初始化的*/对象和一个带有单个声明/定义的指针
obj
是指针(在大多数情况下),
*obj
(或
obj[0]
)是对象。如果您确定obj1不再被引用,则可能是您可以删除的一些遗留遗忘代码。但可能引用了
obj2
,而
obj1
是通过传递指针而不是对象本身来访问的。如果
obj1
是一个
struct
,那么整个
struct
将被传递给一个函数,但作为
obj2
,只是一个指针。您需要检查指针
obj2
在程序中的后续使用方式。由于您还没有展示,我们无法真正告诉您您的替换是否合理。这完全取决于我们在这里看不到的用例。您应该向我们展示一些代码行,说明如何使用
obj2
。也许这只是奇怪的代码,如果看不到更多,很难分辨。而且,相信我,在野外有很多奇怪的代码。这是唯一有意义的答案(实际上是一个非常详细的评论)+从我这里得到1。