通过引用修改结构与其他指针之间的区别

时间:2009-12-04 02:01:43

标签: c data-structures pointers reference arguments

我想知道为什么结构指针的行为与char指针的行为不同。

typedef struct person_struct {
    char *name;
} person;

changeStructName(person * name1) 
{
name1->name = "Robert";                       
}

changeCharName(char * name2) 
{
name2 = "Jose";                       
}

int main()
{
person * name1;
char * name2;

name1 = malloc(1 * sizeof(person));
changeStructName(name1);
changeCharName(name2);

printf("First name is %s\n",name1->name);
printf("Second name is %s\n",name2);
  }   

我知道使用此代码会起作用:

changeCharName(char ** name2) 
{
*name2 = "Jose";                       
}

changeCharName(&name2);

我只是好奇为什么我不需要对结构的指针设置做同样的指针,以便通过引用进行修改?

6 个答案:

答案 0 :(得分:8)

在ChangeCharName的第一个版本中,您只修改了函数本地的指针副本。 name1的原始值保持不变。通过引用传递指针(在函数的第二个版本中)允许您更改指针的原始值(由main()看到)。

答案 1 :(得分:4)

指向结构的指针将允许您修改该结构的内容,但不能修改指针指向的结构。

答案 2 :(得分:2)

请注意,->运算符与(* ).相同 - 所以这意味着您的行:

name1->name = "Robert";

与:

相同
(*name1).name = "Robert";

...看起来更像是changeCharName的替代配方,不是吗?

答案 3 :(得分:1)

考虑char ** name2中显式的双重间接也存在person * name1,因为您已将char *封装在其他内容中,然后复制指向该容器的指针。因此,当您取消引用name1时,您可以访问要更改的char *

答案 4 :(得分:1)

在您的代码中,name1已取消引用,但name2未被解除引用。尝试

(*name1).name = "Robert";

*name2 = "J";

我希望你会看到相似之处。此外,要使此示例起作用,您需要初始化name2以指向某些可变存储。例如,

char *name2 = malloc(99);
strcpy(name2, "Rose");

然后您将"Rose"更改为"Jose"

我建议您观看视频Pointer Fun with Binky

答案 5 :(得分:1)

回想一下,C只按值传递参数。

在您的示例中,

changeCharName(char * name2)
{
  name2 = "Jose";
}

当您调用changeCharName()时,您在main()过程中传递了变量name2中包含的值。 (该值实际上是垃圾,因为您从未在任何地方指向name2。)当changeCharName()运行时,它将传递的值保存在本地临时值中,然后将该本地临时值更改为包含固定字符串的地址。但是,当changeCharName()返回时,(更新的)本地临时变为所有临时变量的路径。

在您的修改版本中,您在main()中传入了局部变量name2的ADDRESS,并且您编写了THROUGH该地址以更改存储在该局部变量中的值。

这就是为什么计算机科学专业的学生在职业生涯的早期就采用汇编语言,因此他们理解“地址”的真正含义。这也是FORTRAN,PASCAL和Ada通过引用传递参数的原因,以及为什么BLISS将解除引用地址作为一种显式操作。