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



程序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函数都将指针作为参数。你能解释一下&和*运算符,同时调用带有示例的函数。提前谢谢。

当您将一些&作为arguments发送到任何函数的parameters时,应该有*来保存该&,或者如果函数的parameters中有任何*,则可以像&*一样发送arguments。这只是关系。

程序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;

您需要发送&st,因为将&st发送到create()可以访问存储st的内存。如果将st(它只是存储st数据的内存位置的名称(作为参数发送到create(),则只会将st复制到struct Stack *st中,并导致错误。并且不能像scanf("%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;
}

您已经有了存储struct Node类型的data的内存地址,即first的值。这就是为什么在这种情况下不需要执行display(&first),只需复制first并在display()函数中使用它。

你能解释一下&和*运算符,同时调用带有示例的函数。

但您也可以在程序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;
}

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

无论x&x的类型允许获得x的地址,无论目标是什么。如果您需要获得x的值,请使用x如果您需要获取其地址,则使用&x

在第一个给出st地址的程序中,允许create修改它,因此在main中,从reate返回变量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;
}

在这种情况下,createstmain复制并返回main进行操作,st没有变化

进行时

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

目标是读取int并将其存储在字段size中,因此需要给出该字段的地址,因此&st->size而不是st->size,后者给出其值


在第二个程序中,第一个已经是一个指针,这就是为什么中的调用是display(first);而不是display(&first);,无论如何,请注意值为NULL的第一次显示无效,因为(p!=NULL)立即为假

当然,你也可以用&first首先得到的地址,但在这种情况下,你得到的是struct Node **,所以假设display(&first);显示必须更改为void display(struct Node ** p),当然它的主体必须适应

如果要更改函数中的原始对象而不是其副本,则必须通过引用传递它。在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;
}

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

最新更新