在用 C 语言调用函数时,什么时候应该添加“&”,什么时候不应该添加“&”?

when should we add '&' and when we shouldn't while calling a function in c language?

提问人:Animux 提问时间:7/13/2020 最后编辑:Vlad from MoscowAnimux 更新时间:7/13/2020 访问量:167

问:

程序 A

void create(struct Stack *st) 
{
    printf("Enter Size");
    scanf("%d",&st->size);
    st->top=-1;
    st->S=(int *)malloc(st->size*sizeof(int));
}

int main()
{
struct stack st;
create(&st);
return 0;
}

程序 B - 对于程序 B,假设已创建一个链表,其中第一个(声明为全局变量)指向列表中的第一个节点。

struct Node 
{ 
 int data;
 struct Node *next;
}*first=NULL;

void display(struct Node *p) 
{
while(p!=NULL)
{
 printf("%d ",p->data);
 p=p->next;
}
} 

int main()
{
display(first);
return 0;
}

我的疑问是,为什么在程序 A 中调用 create 函数时,需要 & 运算符,为什么在程序 B 中调用显示函数时不使用它。create 和 display 函数都采用指针作为参数。您能否通过示例解释 & 和 * 运算符之间的关系,同时调用函数。提前致谢。

C 指针 结构 Pass-By-Reference Pass-By-Value

评论

0赞 Jonathan Leffler 7/13/2020
当您有一个变量并且需要将指向该类型变量的指针传递给函数时,可以使用。如果您已经有指向正确类型的指针,则不要使用 .&&
0赞 bruno 7/13/2020
&x允许获取 X 的地址,无论其用途如何,如果需要获取 X 的值,请使用 如果您需要获取其地址使用x&x
0赞 Weather Vane 7/13/2020
在第二个程序中,传递的变量已经是一个指针。它被定义为 .*first
0赞 Shubham 7/13/2020
当你发送一些关于任何函数的 时,应该有 。这仅仅是关系。&argumentsparameters*&

答:

2赞 bruno 7/13/2020 #1

无论 x 的类型如何,无论目标如何,都可以获取 x 的地址。如果需要获取 x 的值,请使用 如果需要获取其地址,请使用&xx&x

在第一个给出地址的程序中,st 允许 create 修改它,所以在 main back 中,从 create 开始修改变量 st

但是有:

void create(struct Stack st) 
{
    printf("Enter Size");
    scanf("%d",&st.size);
    st.top=-1;
    st.S=(int *)malloc(st.size*sizeof(int));
}

int main()
{
  struct stack st;
  create(st);
  return 0;
}

在这种情况下,创建工作在从 Main 和 Back 到 Main 的 ST 副本上,ST 没有变化

做的时候

scanf("%d",&st->size);

目标是读取一个并在字段大小中记住它,因为需要给出该字段的地址,而不是给出它的值int&st->sizest->size


在第二个程序中,首先已经是一个指针,这就是为什么在 main 中的调用是而不是,无论如何注意首先评估 NULL 显示没有任何作用,因为立即是假的display(first);display(&first);(p!=NULL)

当然,你也可以得到第一个的地址,但在这种情况下,你会得到一个假设的显示必须改变,当然它的主体必须适应&firststruct Node **display(&first);void display(struct Node ** p)

1赞 Vlad from Moscow 7/13/2020 #2

如果要更改函数中的原始对象而不是其副本,则必须通过引用传递它。在 C 语言中通过引用传递意味着通过指向对象的指针间接传递对象。

例如,如果在第一个程序中,您将编写

void create(struct Stack st) 
{
    printf("Enter Size");
    scanf("%d",&st.size);
    st.top=-1;
    st.S=(int *)malloc(st.size*sizeof(int));
}

int main()
{
struct stack st;
create(st);
return 0;
}

然后,该函数将处理传递给该函数的对象 ST 的副本。更改副本对原始对象没有影响。

在第二个程序中

struct Node 
{ 
 int data;
 struct Node *next;
}*first=NULL;

void display(struct Node *p) 
{
while(p!=NULL)
{
 printf("%d ",p->data);
 p=p->next;
}
} 

int main()
{
display(first);
return 0;
}

该函数处理指针的副本。指针本身不会在函数中更改。因此,通过引用传递它是没有意义的。另一方面,指针指向的节点通过引用传递。因此,编译器不会创建 struct Node 类型的对象的副本。如果需要,您可以更改函数中的指向节点。displayfirst

评论

0赞 Shubham 7/13/2020
是的,我明白了。
2赞 Shubham 7/13/2020 #3

当你向任何函数发送一些时,应该有 保持它,或者如果函数中有任何,你可以发送 like 或 。这仅仅是关系。&argumentsparameters*&*parametersarguments&*

程序 A 中:

void create(struct Stack *st) 
{
    printf("Enter Size");
    scanf("%d",&st->size);
    st->top=-1;
    st->S=(int *)malloc(st->size*sizeof(int));
}

int main()
{
struct stack st;
create(&st);
return 0;

您需要发送,因为发送到可以为您提供对存储位置的内存的访问。如果你发送 -- 这只是存储数据的内存位置的名称 -- 作为参数,那将只是将 into 复制到并导致错误。而且您不能使用其副本修改原始值,因为在这种情况下,这就是为什么在第一个程序中您需要发送 的地址。&st&stcreate()stststcreate()ststruct Stack *stscanf("%d", &st->size);st

程序 B 中:

struct Node 
{ 
 int data;
 struct Node *next;
}*first=NULL;

void display(struct Node *p) 
{
while(p!=NULL)
{
 printf("%d ",p->data);
 p=p->next;
}
} 

int main()
{
display(first);
return 0;
}

您已经有了存储 of 类型的内存地址,即 的值。这就是为什么在这种情况下你不需要这样做,只需复制并在函数中使用它。datastruct Nodefirstdisplay(&first)firstdisplay()

您能否通过示例解释 & 和 * 运算符之间的关系,同时调用函数。

但你也可以在程序 B 中这样做:display(&first)

struct Node 
{ 
 int data;
 struct Node *next;
}*first=NULL;

void display(struct Node **p) 
{
while(*p!=NULL)
{
 printf("%d ",(*p)->data);
 *p=(*p)->next;
}
} 

int main()
{
display(&first);
return 0;
}

我希望上面给出的示例能够清楚地说明何时使用以及何时调用任何函数,根据其参数。请注意,使用数据会修改 in 的地址,并且指向链表的指针将丢失,因此,此示例仅用于演示目的。*&display&firstfirst*p=(*p)->next;head