Whats the meaning of **(&d) in c? - c

our teacher gave us the following code:
x = **(&d);
His question was: "Which lines of codes do you have to add above this line, so that the code is correct?"
Can anybody help me? What is the meaning of this line?

The remark of DeiDei is a possibility, I just explain more here
We are in C, and to simplify consider x and d are not macros.
x = **(&d); is equivalent to x = *d; because to get the address then dereference does nothing
Now the question is to find a context where x = *d; is legal, for that d has to be a pointer. Let say int * d;
Probably also the goal is to not have a segmentation fault so d need to memorize a valid address. Let say int a; int * d = &a;
Now we assign x with *d so the type of x must be compatible with int Let say int a; int * d = &a; x = **(&d);
To be clean we do not want to access to an uninitialized value, because x finally receive the value of a that one must be initialized.
int a = 0; int* d = &a; int x; x = **(&d); from DeiDei is compatible with the requirement, but of course they are plenty of other solutions

x = **(&d);
is equivalent to
x = **&d;
is equivalent to
x = *(*&d);
also for any variable v this
v == *&v
holds true.
From the above it concludes that
*&d == d
so
x = *(*&d);
equals
x = *d;
As the dereference operator * can only be applied to a pointer it follows the d has to be of a pointer type
T * d; /* Let be T any type. This defined d to be pointer to that type T. */
Applying to a variable of type T* the operator * the result evaluates to the type T itself.
As it is given
x = *d
from this it concludes that x needs to be of type T.
So the line in question needs to be
T x, *d;
or in a more readable form
T x;
T * d;
:-)

Related

Use of pointers in a division in C99, error: invalid operands to binary

The question surely look stupid, but I have always wasted a lot of time, with tests/errors until it works, with this kind of problem.
I need a pointer to return a value from a function, then I need to divide this value, but I have the compiler error:
invalid operands to binary / (have 'int *' and 'int')
Example in the following code:
void test(int *x, int y)
{
*x = *x+y;
}
int main()
{
int *x = 20;
int y = 1;
test(&x, y);
printf("x: %i", x);
float res = x / 2; // error: invalid operands to binary / (have 'int *' and 'int')
//float res = *x / 2; // application crash with this one. (GCC native Android)
}
I tried with '&' but it didn't work (x = 0), I try cast to int and only get the pointer adress, etc.
Your immediate problem is that you have declared x as a pointer to int, but you are trying to use it as an int. To simply correct the last line, dereference the pointer (just like you've correctly done inside test()):
float res = *x / 2;
Now, it appears you actually tried that and got an error, which is not surprising, because you've initialized x badly:
int *x = 20;
This doesn't create an int value of 20 and make x point to it. It sets x to point at the memory address represented by the integer value 20. That's probably reserved memory, which is why you get an error when you try to dereference it.
(You don't get that error in test() because you've passed the address of x as the argument. So dereferencing it there actually does get you 20 - probably.)
To make the pointers work, either do:
int x = 20;
...
test(&x, y)
...
float res = x / 2;
or:
int *x = malloc(sizeof(int));
*x = 20;
...
test(x, y)
..
float res = *x /2;
But you are really making this too difficult. Since you only need to output one value from the function, just make the function return that value. Then you have no need to mess about with pointers at all:
int test(x,y) { return x+y; }
...
int x = 20;
...
x = test(x,y);
...
float res = x / 2;
(And finally, I believe that in any case you want to use 2.0 in the last line, not just 2, if you want to get a float result instead of an int.)
int * x = 20; means: x is a pointer to an int stored at address 20. When you deference it, the CPU will try to read an int value from address 20, yet address 20 is an invalid address in your current process space and thus your program crashes.
What you probably wanted do say is: x is a pointer to an int and the value of the int it points to is 20, correct? Well, this would have been:
int someInt = 20;
int * x = &someInt;
Now x points to whatever address someInt stores its value (actually it's on the stack space of the main function, but that's just a side node) and the value stored at that address is in fact 20.

using pointers that have ** in c

I am very new to C and currently having some trouble with pointers and I am not sure if my logic is correct on this question clarification would be great.
Is the second expression legal? Why or Why not? What does it mean?
int** x = ....;
... **x ...
This is all the question gives and I came up with the following answer (I think its in the ballpark)
The int** x will initialize a pointer x to whatever address/value that is after the equal sign.
**x ... will dereference the pointer to a value/variable
The question link that was proposed in the edit was just showing the difference between int* p and int *p which is nothing what i asked i understand this already.
int *x is a pointer to int. int** y defines y as a pointer to pointer to int, so it points to a pointer, and the latter points to an int. Example:
int n = 42;
int* x = &n; // points to n
int** y = &x; // points to x, which points to n
In this case y is a pointer to pointer. First indirection *y gives you a pointer (in this case x), then the second indirection dereferences the pointer x, so **y equals 42.
Using typedefs makes everything looks simpler, and makes you realize that pointers are themselves variables as any other variables, the only exception being that they store addresses instead of numbers(values):
typedef int* pINT;
int n = 42;
pINT x = &n;
pINT* y = &x; // y is a pointer to a type pINT, i.e. pointer to pointer to int
If you use double * you are telling the compiler you want a pointer pointing to another pointer:
int x = 4;
int *pointer = &x;
int **pointer_pointer = &pointer;
printf("%d\n",**pointer_pointer); // This should print the 4

What is the difference between `*a =` and `= *a`?

In following function,
void swap(int * a, int * b) {
int t;
t = *a; // = *a
*a = *b; // a* =
*b = t;
}
What is the difference between = *a and *a =?
I've heard that the * operator in = *a is a de-referencing(or in-directing) operator which fetches(?) that value from the pointer.
Then, what is the actual meaning of *a =?
Yesterday, the day I asked this question, I explained about pointers to my colleague whose major field has nothing to do with pointers.
I quickly typed a source code like this.
#include <stdio.h>
void swap1(int a , int b) {
int t = a;
a = b;
b = t;
}
void swap2(int * a, int * b) {
int t = *a;
*a = *b;
*b = t;
}
int main(int argc, char * argv[]) {
int a = 10;
int b = 20;
swap1(a, b);
swap2(&a, &b);
}
I was even proud of myself for remembering things imprinted on my brain in 1996. (I've been with Java for almost 20 years.)
I used a bunch of printfs with %ds and %ps to show her what was happening.
Then I made a terrible mistake. I declared.
포인터 변수 앞에 별을 붙이면 값을 가져온다는 뜻이에요.
When you attach a STAR in front of a pointer variable, that means you fetches(retrieves) the value.
Well that could be applied to following statement.
int t = *a;
Which simply can be said,
int t = 10;
The big problem I faced came from the second statement.
*a = *b; // 10 = 20?
The root evil is that I didn't try to explain about the dereference operator or I didn't ask to myself of being aware of the meaning of a 별(star).
Here is what people would say.
for = *a,
the actual value at the address denoted by a is assigned to the left side.
for *a =
the value of the right side is stored in the address denoted by a.
That's what I'm confusing of. And that's why I should re-think about the meaning of `de-referencing'.
Thanks for answers.
Oh I think this problem is going deeper to the concepts of lvalues and rvalues.
The first one is reading from the memory a is pointing to. The second one is writing to that memory.
This is no different from x = and = x except that you do not access the variable directly but the object it is pointing to.
Here:
t = *a;
the pointer a is dereferenced and this value is assigned to t whereas here:
*a = *b;
both b and a are dereferenced and the value of *b is stored in the address a.
I've heard that the * operator in = *a is a de-referencing(or in-directing) operator which fetches(?)
In fact fetch happens when you dereference a pointer with operator * alone. Hence assignment = operator doesn't involve in dereferencing perhaps assigning the dereferenced value to LHS.
a is a pointer here, pointing to an int.
*a retrieves the integer value stored at memory pointed to by a. When you say *a = <some value>, assuming <some value> to be an int, <some value> gets stored at memory location pointed to by a.
*a = *b ==> Here b is again an int pointer, so integer value pointed to by b is read and written to memory location pointed to by a.
It has no relation with '=' operator .It(* operator) just means value at 'a's address.So
t = *a; assigns value at address a to t
*a = *b; assigns b's value in place of value at address a
*b = t; assigns t to b's value
What is the difference between = *a and *a =?
Well... look at this code:
int x;
t = x;
x = t;
If you have any plain variable int x; then you can read from it and write to it. That's the difference between your two lines as well.
* is the "contents of" operator. If a is a pointer to int, then *a simply means that you can use the contents of that variable as if it had been a plain int variable. And just like any variable you can either read or write to it.

how, where and why someone would use int (*q)[3];

I was reading this question on stackoverflow
C pointer to array/array of pointers disambiguation
I came across int (*q)[3]; // q is a pointer to array of size of 3 integers
The discussion was quite on understanding complex declarations in C.
Iam unable to understand when it is used and how it is used? how do I dereference it? could anyone explain me with some sample codes, like initializing the pointer and dereferencing it.
int main(){
int a =45;
int c[3] = {23};
int b[2][3];
int d[2][5];
int (*q)[3];
b[0][0]=1;
b[0][1]=2;
b[0][0]=3;
q = &a; // warning incompatible pointer type
q = c; // warning incompatible pointer type
q = b; // no warnings works fine
q = d; // warning incompatible pointer type
return 0;
}
After trying the above statements, I understood q can point to an array of n row but 3 column sized array. How do I dereference those values?
printf("%d",*q); gives some strange value 229352.
Could anyone explain me how to initialize and how to dereference the pointers and its memory layout?
Since q can point to an array, you have to
make its value the address of an array: q = &c;, and
dereference it to get an array: ++(*q)[1], printf("%d", (*q)[2]), etc.
Note that the rows of b are also arrays of type int[3], so you can also assign to q the address of each row of b:
q = b + 0; // (*q)[i] == b[0][i]
q = b + 1; // (*q)[i] == b[1][i]
(By contrast, the rows of d have type int[5], so their addresses are not compatible with the type of q, and of course the address of a is also not compatible, since the type if a is int.)

How do I get this address?

I have this:
unsigned int y = (unsigned int)(int*)foo;
How do I get the address to where is stored in memory value which foo points?
Let's try to explain better, assume that thery are of int type:
int x = 10;
int *foo = &x;
unsigned int y = (unsigned int)(int*)foo;
int r = MAGIC(y); /* should be 10 */
x = 13; /* r still should be 10 */
y should hold x's adddress, it is, address of 10 integer.
r should copy the value at y location, it is, 10 integer.
so any change of x (as in x = 13) shouldn't change value r. This just an int.
The question is: How do I define MAGIC?
If what you want is possible, then
#define MAGIC(y) (*((int*)(y)))
will do it.
Your code is trying to use y as a pointer when in fact it is defined to the C-compiler as an unsigned integer. Code that was written back in the "bad ol' days" would do stuff like your example.
Code should be more explicit and well defined in its intent, thus:
#include <stdlib.h>
main()
{
int x = 10;
int *foo = &x;
int *y = foo;
#define MAGIC(A) *A
int r = MAGIC(y); /* should be 10 */
x = 13; /* r still should be 10 */
printf("x=%d, r=%d", x, r);
// printed (as expected) :: x=13, r=10
}
These days there is NO reason to work around a C-compiler!!
If you are maintaining some old code that does stuff like your original example, then it is probably worth the effort to re-write it using today's programming style. Note, it can remain written in C, just well-formed C!
If y is to hold the address of x then it should be declared as:
unsigned int *y;
MAGIC should simply be the what is pointed to by operator.
int r = *y;
MAGIC is just the asterisk.

Resources