Animux
Animux

Reputation: 45

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

Program 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;
}

Program B - for program B assume that a linked list has been created with first(declared as a global variable) pointing at the 1st node in the list.

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;
}

My doubt is, why in program A while calling the create function, the & operator is required and why in program B it is not used while calling display function. Both create and display function take pointer as argument. Can you explain the relationship between & and * operator while calling a function with examples. Thanks in advance.

Upvotes: 3

Views: 233

Answers (3)

Shubham
Shubham

Reputation: 1153

When you send some & as arguments to any function's parameters, there should be * to hold that & or if there's any * in function's parameters you can send arguments like & or *. This is the mere relationship.

In Program 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;

You need to send &st because sending &st to create() provides you the access to the memory where st is stored. If you send st--which is just a name of the memory location, where st's data is stored--as an argument to create() that would be merely copying the st into struct Stack *st and result into an error. And you cannot modify the original value using its copy as in the case of scanf("%d", &st->size); that's why in the first program you need to send the address of st.

In Program 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;
}

You have already the memory address where data of struct Node type is stored, i.e. the value of first. That's why you don't need to do display(&first) in this case just make a copy of first and use it in display() function.

Can you explain the relationship between & and * operator while calling a function with examples.

But you can also do display(&first) in Program B like this:

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;
}

and I hope the example given above makes it clear when to use * and & while calling any function, according to its parameters. Beware, displaying data using &first would modify the address of first in *p=(*p)->next; and your head pointer to the linked list will be lost so, this example is just for demonstration purposes.

Upvotes: 2

bruno
bruno

Reputation: 32596

Whatever the type of x &x allows to get the address of x whatever the goal. If you need to get the value of x use x if you need to get its address use &x

In the first program to give the address of st allows create to modify it, so in main back from create the variable st is modified.

But having :

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;
}

in that case create works on a copy of st from main and back to main there is no change in st

When doing

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

the goal is to read an int and to memorize it in the field size, for that it is needed to give the address of that field, so &st->sizerather than st->size which gives its value


In the second program first is already a pointer, this is why the call in main is display(first); rather than display(&first);, anyway notice first valuing NULL display does nothing because (p!=NULL)is immediately false

Of course you can also get the address of first with &first but in that case you get a struct Node ** so supposing display(&first); display must be changed to void display(struct Node ** p) and of course its body must be adapted

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 311058

If you want to change an original object in a function instead of its copy you have to pass it by reference. Passing by reference in C means passing an object indirectly through a pointer to the object.

For example if in the first program you will write

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;
}

then the function will deal with a copy of the object st passed to the function. Changing the copy has no effect on the original object.

In the second program

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;
}

the function display deals with a copy of the pointer first. The pointer itself is not being changed in the function. So there is no sense to pass it by reference. On the other hand, a node pointed to by the pointer is passed by reference. So the compiler does not create a copy of an object of the type struct Node. You could change the pointed node in the function if it was required.

Upvotes: 1

Related Questions