I m learning C programming and I have seen some code where folks use double pointers. I did some searching on stackoverflow from below but still have a teeny tiny question (Why use double pointer? or Why use pointers to pointers?)
In the code below, my question is I have not defined 'b' as **b. Now
when I try to do (*b) I`m getting a compile error. Isnt this *(*b) same as
*(address of c) because 'a' has address of 'c'.. Why do I need to define 'b' as **b to really get the value of 'c'?
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n," , *a, *(*b));
return 0;
}
Help/explanation is really appreciated :)
EDIT : Thanks a lot guys for the explanation. Things are now clear :)
Here is a working code.
int main()
{
int *a, *b, c;
c=10;
a = &c;
b = a;
printf("*a - %d\n *(*b): %d\n,",*a, *(b));
return 0;
}
Pointers are aptly name: they "point" to locations in memory.
When you write *b, you tell the compiler that you are going to declaring a pointer of type integer so that it points to an integer.
When you use b = a, you tell the compiler that you are assigning the address of c to a as well. Actually, b is a pointer variable itself which is storing the address of an integer variable c. So, this way, you can assign the address of one variable to another pointer as well.
Now, Regarding your code,
int main()
{
int *a, **b, c; // just change it from *b to **b
c = 10;
a = &c;
b = &a;
printf("*a - %d\n *(*b): %d\n,",*a, *(*b));
return 0;
}
You need to specify the compiler that the pointer b is a pointer to a pointer variable by writing 2 *.When you write **b, you are telling the compiler that you are pointing to another pointer variable. Similarly, you can also have triple pointers and Quadrupled pointers as well.
Here is a link for your reference. http://www.c4learn.com/c-programming/c-double-pointer/
In your code, you have to do int **b; because:
a is a pointer-to-integer, since a = &c.
b is a pointer-to-(pointer-to-integer), since you wrote b = &a.
You can access the value of c using *b.. change your code littlebit..
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = a;
printf("*a :%d\n *b: %d\n,",*a, *b);
return 0;
}
*b,*a
defines that a and b are two pointer variable..
a=&c;
Assign the address of the variable c in pointer a.. & stand for address of operator.
b=a;
Copy the contains of a in b.. Now b also contain the address of c..
Print *a and *b.. *a and *b means contain of a and b. So *a and *b will print value of c..
You can also use **b.. **b means b is a pointer which stores address of another pointer variable..
In that case the code will be,
#include <stdio.h>
int main()
{
int *a, *b, c;
c = 10;
a = &c;
b = &a;
printf("*a :%d\n *b: %d\n,",*a, *(*b));
return 0;
}
a contains address of c and b contains address of a.. So, *a will print value of c..
As b is a double pointer we need *(*b) to access the contain of b.. *(*b) will also print the value of c..
Related
In the function read, I need to access the values of integer a and integer b from the main function without declaring them in the prototype of the function read, using pointers.
Pointer x should point to integer a, and pointer y should point to integer b.
#include <stdio.h>
void read(int zzz[], int n) {
int *arr = zzz, *x=a,*y=b;
}
int main() {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
return 0;
}
How this could be implemented?
There are two ways that the read function can read the values or addresses of a and b:
Pass them as parameters
Make a and b global
So if you don't want to make them parameters, you need to move them outside of the main function and before the read function.
Also, read is the name of a system function, so you should name it something else so you don't conflict with it.
You have already received the more conventional answer. It is the most logical choice for your given restriction.
However ... Silly artificial restrictions sometimes deserve a silly contrived solution in kind.
A less conventional way would be to create an understanding with the function that the values will be passed in with the array pointer in some non-standard way.
For example, you can make two extra array members to represent a and b.
int array_for_my_read[array_size + 2];
/* instead of a and b, you use those extra array members */
...
int *x = zzz + n, *y = x + 1;
Alternatively, you could create a special structure that holds the array, and the pointers. Then the function recovers the pointer to the structure from the array pointer.
struct extra_parameters {
int *a;
int *b;
int zzz[zzz_size];
};
...
struct extra_parameters x;
int a, b;
x.a = &a;
x.b = &b;
read(x.zzz, zzz_size);
...
void *p = (char *)zzz - offsetof(struct extra_parameters, zzz);
struct extra_parameters *xp = p;
int *a = xp->a, *b = xp->b;
For example, if there is a pointer variable int *a, int *b and each address value is 1000, 2000, can the address value of the pointer variable be swapped as if it were swapping the value of the common variable?
Note, I mean the address of the pointer. Not the value it contains.
As far as I know, the address value of the pointer variable is fixed and cannot be changed, is that right?
From comments:
A lot of people answered, but I think I asked the wrong question. I'm sorry, but my question is not about "change content of a pointer variable", but "change address of a pointer variable."
No, that's impossible for any variable. Not just pointers.
Can I change the address of the pointer variable in c language?
While the answer to your question would be yes for many other languages, including C++, kind of:
"While C++ doesn't directly support putting a variable at a given address, the same effect can be achieved by creating a reference to
that address:"...
...the answer for C is No. "A pointer has an address like other variables (which can't and needn't be changed)". (quote from 4th response in link.)
For C, the address of all variables (with the exception of those declared as register) are assigned at the time of declaration as a memory location provided by the operating system, and are immutable for the remainder of their life, no matter the scope in which they were created.
So, while the address pointed to by a pointer variable can be changed, the address of the variable itself, cannot.
Yes, you can:
void swapPointers(void **a, void **b) {
void *t = *a;
*a = *b;
*b = t;
}
void someOtherFunc() {
int *x = malloc(sizeof(int));
int *y = malloc(sizeof(int));
*x = 3;
*y = 5;
printf("x = %d y = %d\n", *x, *y);
swapPointers(&x, &y);
printf("x = %d y = %d\n", *x, *y);
}
Yes, you can swap the address the pointer points to.
int main()
{
int x = 5, y = 10;
int* p1 = &x;
int* p2 = &y;
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
//Here goes the swapping
int* p3 = p1;
p1 = p2;
p2 = p3;
printf("\n--After swap--\n");
printf("Address pointed by p1 is: %p\n", p1);
printf("Address pointed by p2 is: %p\n", p2);
}
I think you mean swapping addresses stored in pointers because you can not swap addresses of pointers as declared variables themselves.
To swap two objects in a function you have to pass them by reference. Otherwise the function will deal with copies of the values of passed directly to it objects.
In C passing by reference means passing an object indirectly through a pointer to it.
Pointers are the same objects.
So you can write the swap function the following way
void swap_ptr( int **a, int **b )
{
int *tmp = *a;
*a = *b;
*b = tmp;
}
And the function can be called like
int *a = /*...*/;
int *b = /*...*/;
//...
swap_ptr( &a, &b );
yes you can you just need to swap where each pointer point to.
declare a 3rd pointer then do the swap as follow.
//we have *a and *b
int *tmp;
tmp = a;
a = b;
b = tmp;
yes you can swap the address stored in two pointer using a temporary pointer variable. But if the pointer is declared as constant pointer for exapmle const int *ptr1; then it not possible because the address stored in ptr1 cannot be modified
#include <iostream>
using namespace std;
int main() {
int a=10;
int b=20;
int *ptr1;
int *ptr2;
ptr1=&a;
ptr2=&b;
cout<<ptr1<<" "<<ptr2<<"\n";
int *temp;
temp=ptr1;
ptr1=ptr2;
ptr2=temp;
cout<<ptr1<<" "<<ptr2;
return 0;
}
you can change the syntax to c because I thought that I was answering a question from c++ section
I am trying to swap the value of two integers using pointers, see code below:
void swapArgs(int *a, int *b) {
int *temp = &b;
b = &a;
a = &temp;
printf("Swapped Arguments: A=%d, B=%d\n", *a, *b);
}
When the printf is executed, the resulting values are huge numbers. Can anyone explain to me what is wrong with my code? Still new to pointers.
The problem is that you need to copy the values, not the pointers:
int temp = *b;
*b = *a;
*a = temp;
Note: Your code is assigning pointers of wrong type - &a is int**, while b is int* (i.e. the number of asterisks does not match). Your compiler should have given you warnings about that. Fixing them would fix the problem.
Remember that your a and b are already pointers - so inside the function you must not use the & (address operator), instead you must use the * (dereference operator):
int temp = *b;
*b = *a;
*a = temp;
I'm a bit confused as to why the following code crashes:
int main(){
int *a;
int *b;
*a = -2;
*b = 5; //This line causes a crash on my system.
return 0;
}
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
Or must you always explicitly allocate memory?
No. You've only declared the pointers, not what they point to. The pointers are allocated on the stack, and since you've not initialized them to anything, their values are garbage.
int main() {
int a = 7;
int *p_a; // p_a contains whatever garbage was on the stack at its
// location when main() is called. (Effectively points nowhere).
p_a = &a; // p_a points to (gets the address of) variable a, also on
// the stack.
printf("Before: a = %d\n", a); // prints 7
*p_a = -2;
printf("After: a = %d\n", a); // prints -2
return 0;
}
I would code up the above example, and step through it in a debugger. You'll see what I mean about what p_a is pointing to.
Shouldn't memory automatically be allocated for two pointers and two integers before run-time because of the declarations?
I only see you specifying two pointers. Where are the two integers?
Or must you always explicitly allocate memory?
Pointers have to point to something. Either local variables on the stack, or malloc'd memory from the heap.
In this code:
int* a;
*a = -2;
a is an uninitialized pointer, dereferencing of which produces undefined behavior, that you were luckily able to observe as a crash of your application.
You need to initialize the pointer (make it point to the valid memory) before you dereference it (i.e. before you use *, the dereference operator):
int a;
int* pA = &a;
*pA = -2;
Consider
int m;
int n;
m = n;
This is invalid because you're trying to use n but you haven't assigned a value to it. Now:
int *a;
*a = -2;
Likewise, this is invalid because you're trying to use a but you haven't assigned a value to it. The value of a is not an int, it's a pointer to int. For example,
int someint;
a = &someint;
*a = -2;
puts -2 into someint. Without the assignment to a, the place to put -2 is undeterminable. Also,
a = malloc(sizeof(int));
*a = -2;
Here, a is given the value of the address of some location in the heap; -2 goes into that heap location.
Perhaps an analogy would be helpful:
Consider the phrase "her dog". This is a reference to someone's' dog, but it won't do to tell me "give her dog a bone" if you haven't told me who she is. Similarly, "pointer to an int" doesn't tell the system which int it is.
Your *a and *b pointers are not initializated properly.
Try this one:
int my_a;
int my_b;
int *a;
int *b;
a = &my_a; // init the pointer a to the direction of my_a int variable
b = &my_b;
*a = 3; // set the my_a value via pointer
*b = 2;
You have just declared pointers but you haven't initialized them. So, you can't be sure that *b = 5 is causing the program to crash. It could be *a = -2 as well. To fix it, you should initialize your pointers as well.
int aval = -2;
int bval = 5;
int *a = &aval; // declared and initialized pointers
int *b = &bval;
// Now you can change the value using the pointer
*a = 15;
*b = 20;
I'm new to C and still trying to grasp the concept of pointers. I know how to write a swap function that works...I'm more concerned as to why this particular one doesn't.
void swap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(a, b);
printf(ā%d %d\nā), *a, *b);
}
You're missing *s in the swap function. Try:
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
That way, instead of just swapping the pointers, you're swapping the ints that the pointers are pointing to.
Your swap() function does work, after a fashion - it swaps the values of the variables a and b that are local to swap(). Unfortunately, those are distinct from the a and b in main() - so you don't actually see any effect from swapping them.
When thinking about pointers, you need to be clear on a few abstractions.
An object in memory. This can be of any type (and size). An integer object, for example, will occupy 4 bytes in memory (on 32 bit machines). A pointer object will occupy 4 bytes in memory (on 32 bit machines). As should be obvious, the integer object holds integer values; a pointer object holds addresses of other objects.
The C programming language lets symbols (variables) represent these objects in memory. When you declare,
int i;
the symbol (variable) i represents some integer object in memory. More specifically, it represents the value of this object. You can manipulate this value by using i in the program.
&i will give you the address of this object in memory.
A pointer object can hold the address of another object. You declare a pointer object by using the syntax,
int* ptr;
Just like other variables, the pointer variable represents the value of an object, a pointer object. This value just happens to be an address of some other object. You set the value of a pointer object like so,
ptr = &i;
Now, when you say ptr in the program, you are referring to its value, which is the address of i. But if you say *ptr, you are referring to not the value of ptr, but rather the value of the object whose address is in ptr i.e. i.
The problem with your swap function is that you are swapping values of pointers, not the values of objects that these pointers hold addresses for. To get to the values of objects, you would have to use *ptr.
C is a pass-by-value language. Your swap routine doesn't dereference the pointers passed to it, so from main's perspective nothing has happened.
The pointers are passed by value. This means a & b are still a and b when the come back from the function;
try something like this
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
The right way to do it:
void swap(int* a, int* b)
{
int temp = *a; // Temp is set to the value stored at a (5)
*a = *b; // value stored at a is changed to the value stored at b (10)
*b = temp; // value stored in address b is changed to 5.
}
It does swap. It swaps local pointers a and b inside swap function. It swaps them perfectly fine, as it should.
If you want to swap the values these pointers are pointing to, you should re-implement your swap function accordingly, i.e. make it swap the pointed values, not the pointers.
Umm maybe using this
void swap(int** a, int** b)
{
int** temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(&a, &b);
printf(ā%d %d\nā), *a, *b);
}
Without using a third variable (temp)
void swap(int* a,int* b)
{
// a = 10, b = 5;
*a = *a + *b; // a now becomes 15
*b = *a - *b; // b becomes 10
*a = *a - *b; // a becomes 5
}
zildjohn1's answer is the easiest and clearest way to do it. However if you insist on swapping the pointers, then you have to pass the pointer to the pointer because the pointer itself is passed by value.
You need to send the address of a and b for swap function so while calling swap function you must call ass swap (&a,&b)
So that you pass the address, and alter the address
#define SWAP(a,b) ((a)=(b)+(a),(b)=(a)-(b),(a)=(a)-(b))
Works good.