please explain exactly why do i use pointer on non array variable such as int i know pointer variable store the address of specified variable but why do we need address of just single variable, what is the advantage of doing this?
int a = 10;
int *ptr_a = &a;
Thanks!
Although I guess the code you're looking at should give you an answer ... the typical reason this is done is for passing it to a function that should be able to modify this variable.
if you just call foo(a), the function foo() will receive the value of the variable as an argument, so it has it's own copy. The same thing happens with a pointer, but the pointer will of course still point to your original variable, so the function could modify it by dereferencing the pointer (*a = 42;).
By using pointer we achieve call by reference mechanism
please compile below snippet by removing the pointer and note the output.
#include <stdio.h>
void swap(int *a,int *b);
int main(){
int num1=5,num2=10;
swap(&num1,&num2); /* address of num1 and num2 is passed to swap function */
printf("Number1 = %d\n",num1);
printf("Number2 = %d",num2);
return 0;
}
void swap(int *a,int *b){ /* pointer a and b points to address of num1 and num2 respectively */
int temp;
temp=*a;
*a=*b;
*b=temp;
}
Explanation:
The address of memory location num1 and num2 are passed to function and the pointers *a and *b accept those values. So, the pointer a and b points to address of num1 and num2 respectively. When, the value of pointer are changed, the value in memory location also changed correspondingly. Hence, change made to *a and *b was reflected in num1 and num2 in main function.
This technique is known as call by reference in C programming.
Related
void main(){
int a = 100;
int* pa = &a;
*pa = 999;
}
The above code will make the value of a to 999. But why not the pointers to structures treated the same way?
struct node* head = (struct node*) malloc(sizeof(struct node));
head -> data = 6;
head -> next = NULL;
Why can we not use *head -> data = 6? And why passing someMethod(pa) is pass by reference and someMethod(head) is pass by value? reference
Why can we not use *head -> data = 6?
Because -> is a dereference operator that replaces the asterisk *. You can rewrite with an asterisk, too
(*head).data = 6
You need parentheses because dot has higher precedence than indirection. Operator -> has been introduced to make indirection more readable in case of pointers to structs.
why passing someMethod(pa) is pass by reference and someMethod(head) is pass by value?
It's all pass by value, because pointers are passed by value, too. Passing a pointer lets you reference the original variable and modify it, but the pointer itself is copied.
First question's answer, you have got already.
For second Question, Consider three variables, A,B,C where A & C are integer Variables and B is a integer Pointer. Variable names, their values and address(assumed to see a memory map)
has been shown in picture.
see this code
void fun(int *b,int *c)
{
printf("\nfun %d",*b);
b=c;
}
void fun1(int **b, int *c)
{
printf("\nfun1 %d",**b);
*b=c;
}
int main()
{
int a=10;
int c=200;
int *b=&a;
printf("\n %d %d %d",a,*b,c);
fun(b,&c);
printf("\n %d %d %d",a,*b,c);
fun1(&b,&c);
printf("\n %d %d %d",a,*b,c);
return 0;
}
In main(),a & c are local integer Variables, having different data and b is a integer pointer. We are calling function fun() like this,
fun(b,&c);
Since, b is a pointer so, we are passing the value of b i.e address of a (1000).
so if we modify the b inside function fun(), that change will reflect inside the fun() only.
Now we call the function fun1(),
fun1(&b,&c)
Here, we are passing the address of b i.e (3000). so, when we modify the b inside the fun1() , we see the reflection in main() as well.
so, passing by value means, we want to use values without modifying the original pointer present in calling function( main() ). but we pass by reference, when we need any significant change which should reflect in our calling function( main() ) itself.
I hope, this clears the doubt.
I discovered that if you assign a pointer address to another pointer's address in a FUNCTION it won't change the in value in the main,
however by doing the same thing in main, it will change. So what is the reason of this?
void func(int *a, int *b){
b = a;
}
int main(){
int i= 5, k =6, *a=&i, *b=&k;
printf("%d %d\n",*a,*b); //output 5 6
b = a;
printf("%d %d\n",*a,*b); //output 5 5
a=&i;
b=&k;
func(a,b);
printf("%d %d\n",*a,*b); //output 5 6
printf("%d %d\n",*a,*b); //output 5 6
}
In this function
void func(int *a, int *b){
b = a;
}
parameters a and b are local variables of the function. After exiting the function they will be destroyed. The function deals with copies of arguments. If you want that the function would change the original arguments themselves you have to pass pointers to them. For example
void swap(int **a, int **b){
int *tmp = *a;
*a = *b;
*b = tmp;
}
Your function:
void func(int *a, int *b){
b = a;
}
doesn't do anything, it just takes two values representing memory addresses as parameters and assigns one to the other without any external effect whatsoever. It just writes the value of the one to the other (probably not even that, because the compiler will likely detect this is pointless and eliminate it altogether), it doesn't do anything with the information stored at those addresses. You will need to deference the pointer to read or write to the memory address it holds the value of, but in the present form, the function will not assign the pointer to the other, but the value of i to k.
If you want a function to change a parameter outside of it, you should pass by reference, which in C is just pass by pointer, so you need to pass a pointer to the pointer, not the pointer - which will pass a copy of that pointer - the same value, while passing as pointer to pointer will pass the address of the pointer in memory, not the value it holds.
So it should be:
void func(int **a, int **b){
*b = *a;
}
and func(&a,&b) and you will reproduce what you do in main via b = a.
void swap(char *a,char *b){
char t;
t = *a;
*a = *b;
*b = t;
}
int main(void){
char a = '1';
char b = '2';
swap(&a,&b);
printf("The value is %c and %c respectively\n",a,b);
return 0;
}
in the above code, there's a spot that confuse me
I think if a is a pointer, and *a is the value it points to
int *ptr, a = 1;
ptr = &a;
printf("The value of *ptr should be a: %d\n",*ptr);
printf("The value of *a should be an hex address: %p\n",ptr);
so in the swap(char *a, char *b) function,it takes the value not pointer( *a not a),
swap(&a, &b)
but it actually pass the pointer value to it as the parameter, and the code works. Anybody can explain it to me?(I think for swap(char *a){...} part, the declaration doesn't mean it require *a to pass in, it means declare a pointer value a, not the value a points to as *ain elsewhere means).
* is confusing because it means two different, but closely related, things. In a variable declaration, * means "pointer". In an expression, * means "dereference the pointer".
It's intended to be a helpful mnemonic: if you have char *a in your code it means that *a is a char.
Your function
swap(char *a, char *b)
takes two parameters, both of which are of type char *. Quite literally that means they point to a character somewhere in memory.
When you dereference the pointer
t = *a;
You are saying "grab whatever a is pointing to and put it in t.
Perhaps the confusion is from the fact that * means two related but different things. In the case char *, it's defining a type, specifically one that points to a character somewhere in memory. In the case *a, the * means "look at the character being pointed to by a and let me know what it is".
In main:
a is a char
&a is a pointer to the char a.
In swap:
a is a pointer to a char
*a is the char pointed to by a.
You passed a pointer to a pointer, and it worked beautifully. Try drawing a picture with boxes and errors. Clears things up every time. Just remember your code has two as and two bs.
Yes, the asterisk * has multiple meanings related to pointers:
It be used in a declaration to introduce a variable that contains an address - a pointer:
int *ptr = NULL;
Similarly in an argument list, such as void swap(char *, char *).
It can also be used to dereference an existing pointer, or get the value pointed to, as within the function swap:
t = *a;
This generally causes a good deal of confusion for students who are new to C, but it's actually quite simple.
In this our aim is to swap the value
when you write char a='1'; i.e you are putting '1' at address 662442(suppose &a=662442).
char b='2'; i.e you are putting '2' at address 662342(suppose &b=662342).
now consider swapping a and b,here our aim is to change value at 662442(&a) to value at 662342(&b) and value at 662342(&b) to value at 662442(&a).
now for swapping we take a temporary variable char temp and will do the following
temp=*a; i.e assigning value at address 662442(&a) to temp.
*a = *b; i.e assigning value at address 662342(&b) to value at address 662442(&a).
now we will put previous value of a (i.e value kept in variable temp) at address 662342(&b)
*b = temp; i.e assigning temp to address 662442(&a)
I would just like to confirm that when I have a function of the sort
int subtract(int a, int b)
{
return a-b;
}
I am passing values when i call subtract(3,2) rather than pointers.
Thanks,
Yes you are
a parameter of type int a means pass an integer by value to the function
a parameter of type int* a means pass a a pointer to some integer to the function.
so for this
int subtract(int a, int b)
{
// even if I change a or b in here - the caller will never know about it....
return a-b;
}
you call like this:
int result = substract(2, 1); // note passing values
for pointers
int subtract(int *a, int *b)
{
// if I change the contents of where a or b point the - the caller will know about it....
// if I say *a = 99; then x becomes 99 in the caller (*a means the contents of what 'a' points to)
return *a - *b;
}
you call like this:
int x = 2;
int y = 1;
int result = substract(&x, &y); // '&x means the address of x' or 'a pointer to x'
Yes, C always pass function parameters by value . To pass a pointer you have to specify the star (asterisk) that identify the pointer type.
Bear in mind that C always pass by value function parameters even in the case of a pointer, in that case the address of the pointer is actually copied .
Yes, you are passing values. A pointer would be denoted by an asterisk after the type name and before the variable name.
" Double pointers are also sometimes employed to pass pointers to functions by reference "
can somebody can explain me the above statement, what exactly does point to function by reference means ?
I believe this example makes it clearer :
//Double pointer is taken as argument
void allocate(int** p, int n)
{
//Change the value of *p, this modification is available outside the function
*p = (int*)malloc(sizeof(int) * n);
}
int main()
{
int* p = NULL;
//Pass the address of the pointer
allocate(&p,1);
//The pointer has been modified to point to proper memory location
//Hence this statement will work
*p=10;
//Free the memory allocated
free(p);
return 0;
}
It means that you have a function that takes a pointer pointer (type int ** for example). This allows you to modify the pointer (what data it is pointing to) much in the way passing a pointer by reference would allow.
void change (int *p) {*p = 7;}
void Really_Change (int **pp) {*pp = null;}
int p = 1;
int *pp = &p;
// now, pp is pointing to p. Let's say it has address 0x10;
// this makes a copy of the address of p. The value of &p is still 0x10 (points to p).
// but, it uses that address to change p to 7.
change(&p);
printf("%d\n", p); // prints 7;
// this call gets the address of pp. It can change pp's value
// much like p was changed above.
Really_Change(&pp);
// pp has been set to null, much like p was set to 7.
printf("%d\n", *pp); // error dereference null. Ka-BOOM!!!
So, in the same way that you can pass a pointer to an int and change the value, you can pass a pointer to a pointer and change its value (which changes what it points to.)
I'll try to explain with both code and plain english :). The explanation may get long, but it will be worth the while.
Suppose we have a program, running its main() function, and we make a call to another function that takes an int parameter.
Conceptually, When you pass a variable as a parameter to a function, you can do so in (roughly speaking) two ways: by value, or by reference.
"By value" means giving the function a copy of your variable. The function will receive its "content" (value), but it won't be able to change the actual variable outside its own body of code, because it was only given a copy.
"By reference", on the other hand, means giving the function the actual memory address of our variable. Using that, the function can find out the variable's value, but it can also go to that specified address and modify the variable's content.
In our C program, "by value" means passing a copy of the int (just taking int as argument), and "by reference" means passing a pointer to it.
Let's see a small code example:
void foo(int n) {
n = 10;
printf("%d\n", n);
}
int main() {
int n = 5;
foo(n);
printf("%d\n", n);
return 0;
}
What will the output of this program be? 10 10? Nope. 10 5! Because we passed a copy of the int, by value and not by reference, foo() only modified the number stored in its copy, unable to reach main()'s copy.
Now, if we do it this way:
void foo(int* n) {
*n = 10;
printf("%d\n", *n);
}
int main() {
int n = 5;
foo(&n);
printf("%d\n", n);
return 0;
}
This time we gave foo() our integer by reference: it's actual memory address. foo() has full power to modify it by accessing it's position in memory, foo() and main() are working with the same copy, and so the output will be 10 10.
As you see, a pointer is a referece,... but also a numerical position in memory. It's similar to an int, only the number contained inside is interpreted differently. Think of it this way: when we pass our int by reference, we're passing an int pointer by value!. So the same by value/by reference logic can be applied to pointers, even though they already are references.
If our actual variable was not an int, but an int reference (pointer), and we wanted main() and foo() to share the same copy of that reference so that foo() can modifiy it, what would we do? Why of course, we'd need a reference to our reference! A pointer to a pointer. That is:
int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
Stores int*'s memory address so we can pass int*s by reference. */
I hope this was useful.