pointer * and & difference - pointers

I am confused on pointers in objective-c. I wrote a very simple program to try and understand
char* temp = "temp";
printf("temp - %s \n", temp);
printf("*temp - %d \n", *temp);
printf("&temp - %s \n", &temp);
printf("&(*temp) - %s \n", &(*temp));
In this example, temp is a pointer to char with a default value of "temp". What does *temp, &temp mean? The output is:
temp - temp
*temp - 116
&temp - 00#
&(*temp) - temp
So temp is the pointer. When I print temp, it prints the value "temp". *temp is the value of the pointer or the address of the variable it points to. What is &temp? Is this the address of the pointer itself?
I wrote a second program in which I assign pointer to address of n (&n).
int n = 50, x;
int *ptr;
ptr = &n;
x = *ptr;
printf("n - %d\n", n);
printf("ptr - %d\n", ptr);
printf("*ptr - %d\n", *ptr);
printf("x - %d\n", x);
The output is:
n - 50
ptr - 2271924
*ptr - 50
x - 50
n is 50 and x is undefined. ptr points to address of n. Why does *ptr print 50 and *temp prints 116? Is the difference between how I have defined the two pointers? I am trying to understand the basics. Thank you.

When we print out *temp, we go to the temp variable, locate the address that it holds (the one it points to), than print out whatever data is in that location.
When we print out &temp, we are asking for the address of the temp variable, not what it is pointing to.
For your second program, you assign the address of n (using &) to ptr. This way, when we choose to call *ptr, it's gonna locate the address stored in ptr (which is n's), and print out whatever n holds. So you then assigned the value *ptr points to, and store it in x.
In summary, when declaring a pointer, & will print out the address of the variable, * will print out what it points to, and nothing in front will print out the address of the variable it's pointing to.

Related

Pointer in func parameter: copy by value or by pointer

here is the code:
package main
import "fmt"
func double(x *int) {
fmt.Printf("pointer of pointer #1: %p\n", &x)
fmt.Printf("pointer#1 : %p\n", x)
*x += *x
x = nil
fmt.Printf("pointer#2 : %p\n", x)
fmt.Printf("pointer of pointer #2: %p\n", &x)
}
func main() {
var a = 3
double(&a)
fmt.Println(a) // 6
fmt.Printf("pointer a in main: %p\n", &a)
p := &a
double(p)
fmt.Println(a, p == nil) // 12 false
fmt.Printf("pointer p in main: %p\n", p)
fmt.Printf("pointer of pointer p in main: %p\n", &p)
}
or in playground.
Question 1: pointer parameters in functions get copy of pointer or get directly pointer?
Question 2: why value x in double function is the same as &a in main func?
Question 3: if x has the same value as &a then why when x = nil &a stil has value and not nil?
Question 1: pointer parameters in functions get copy of pointer or get directly pointer?
The distinction this question is trying to make suggests a certain lack of background understanding.
Think of a pointer as a number / address which can be used to access some other data. A copy of this address just copies a number. Is 42 the same as a "copy of 42"? Yes, in a sense.
x := &value // x holds the address of value now
y := x // and now y does, too
Given the above two lines, assigning x to something else does absolutely nothing to change value or &value. It simply reassigns x to another address. However, doing something like *x = 999 changes value itself because x holds the address of value and the redirection *x means access to value.
If this isn't 100% clear, try to work through the Tour of Go starting here.
Question 2: why value x in double function is the same as &a in main func?
Because of the explanation above. &a is the address of a - it's a number, think 42 again (the real address is something like 0x40e020, but let's call it 42 for simplicity). When you pass it into a function accepting a *int, 42 gets copied and x in double becomes 42. Now both x inside double and &a outside it have the address of a in them.
Question 3: if x has the same value as &a then why when x = nil &a stil has value and not nil?
Because x just has the value 42 in it, which happens to be the address of a. If you assign anything else to x, that doesn't change the address of a, does it? It changes x. x will no longer point to a.

When does a pointer variable has its address changed?

Consider the following example and notice how the location of pointer variable a remains fixed, as expected:
var a *int
v1 := 1
v2 := 2
a = &v1
fmt.Printf("%p\n", &a) // output: 0x1040c128
a = &v2
fmt.Printf("%p\n", &a) // output: 0x1040c128
Now consider the following struct definition:
type foo struct {
bar int
}
If a is declared as a pointer variable to foo as in this example, its location in memory does not remain fixed.
var a *foo
v1 := foo{bar: 1}
v2 := foo{bar: 2}
a = &v1
fmt.Printf("%p\n", a) // output: 0x10414020
a = &v2
fmt.Printf("%p\n", a) // output: 0x10414024
Why is that?
Are you sure you just didn't make a typo and used fmt.Printf("%p\n", a) instead of fmt.Printf("%p\n", &a) because the first one uses &a and your second example uses a.
Long answer:
With
fmt.Printf("%p\n", a)
you're printing out the value of a which is of type *foo which is a pointer. Roughly speaking a pointer is a variable holding an address of a memory location. With
a = &v1
you set a to the address of v1
a = &v2
you set a to the address of v2. v1 and v2 have different locations in memory and thus you when you print the value of a you'll see exactly that.
If you use
var a *foo
v1 := foo{bar: 1}
v2 := foo{bar: 2}
a = &v1
fmt.Printf("%p\n", &a)
a = &v2
fmt.Printf("%p\n", &a)
then you'll see the same number printed twice because now you're printing out the location of a. So:
a = &v
fmt.Printf("%p\n", a) // prints location of v, not location of a
a = &v
fmt.Printf("%p\n", &a) // prints location of a, not location of v
Remark:
There's some ambiguity as to what people call a pointer and what an address. Some say that a pointer is an address because it contains an "address of a memory location" but a pointer is not actually a memory address depending on the exact context. Also, a points to b usually means that a is a pointer containing the address of b. Likewise, &v is either referred to as "the address of v" and "a pointer to v" which (at least in my opinion) are equally correct which is why I originally used "set a to a pointer to v".

Why does this binary math fail when adding 00000001, but work correctly otherwise?

I've tried everything I can think of and cannot seem to get the below binary math logic to work. Not sure why this is failing but probably indicates my misunderstanding of binary math or C. The ultimate intent is to store large integers (unsigned long) directly to an 8-bit FRAM memory module as 4-byte words so that a micro-controller (Arduino) can recover the values after a power failure. Thus the unsigned long has to be assembled from its four byte words parts as it's pulled from memory, and the arithmetic of assembling these word bytes is not working correctly.
In the below snippet of code, the long value is defined as four bytes A, B, C, and D (simulating being pulled form four 8-bit memory blocks), which get translated to decimal notation to be used as an unsigned long in the arrangement DDDDDDDDCCCCCCCCBBBBBBBBAAAAAAAA. If A < 256 and B, C, D all == 0, the math works correctly. The math also works correctly for any values of B, C, and D if A == 0. But if B, C, or D > 0 and A == 1, the 1 value of A is not added during the arithmetic. A value of 2 works, but not a value of 1. Is there any reason for this? Or am I doing binary math wrong? Is this a known issue that needs a workaround?
// ---- FUNCTIONS
unsigned long fourByte_word_toDecimal(uint8_t byte0 = B00000000, uint8_t byte1 = B00000000, uint8_t byte2 = B00000000, uint8_t byte3 = B00000000){
return (byte0 + (byte1 * 256) + (byte2 * pow(256, 2)) + (byte3 * pow(256, 3)));
}
// ---- MAIN
void setup() {
Serial.begin(9600);
uint8_t addressAval = B00000001;
uint8_t addressBval = B00000001;
uint8_t addressCval = B00000001;
uint8_t addressDval = B00000001;
uint8_t addressValArray[4];
addressValArray[0] = addressAval;
addressValArray[1] = addressBval;
addressValArray[2] = addressCval;
addressValArray[3] = addressDval;
unsigned long decimalVal = fourByte_word_toDecimal(addressValArray[0], addressValArray[1], addressValArray[2], addressValArray[3]);
// Print out resulting decimal value
Serial.println(decimalVal);
}
In the code above, the binary value should result as 00000001000000010000000100000001, AKA a decimal value of 16843009. But the code evaluates the decimal value to 16843008. Changing the value of addressAval to 00000000 also evaluates (correctly) to 16843008, and changing addressAval to 00000010 also correctly evaluates to 16843010.
I'm stumped.
The problem is that you're using pow(). This is causing everything to be calculated as a binary32, which doesn't have enough precision to hold 16843009.
>>> numpy.float32(16843009)
16843008.0
The fix is to use integers, specifically 65536 and 16777216UL.
Do not use pow() for this.
The usual way to do this is with the shift operator:
uint32_t result = uint32_t(byte3 << 24 | byte2 << 16 | byte1 << 8 | byte0);

Increment (++) a dereferenced pointer in a macro --> result is +2 instead of +1

I have the following code:
#include <stdio.h>
#define MIN(x, y) ((x) <= (y) ? (x) : (y))
int main ()
{
int x=5, y=0, least;
int *p;
p = &y;
least = MIN((*p)++, x);
printf("y=%d", y);
printf("\nleast=%d", least);
return 0;
}
I would expect the following result:
y=1
least=1
but instead y=2.
Can somebody explain why y is now 2 and not 1. I suppose that it is because some double incrementation, but I do not understand the mechanism behind it.
Thanks.
Preprocessor macros work by text substitution. So your line:
least = MIN((*p)++, x);
gets expanded to
least = (((*p)++) <= (x) ? ((*p)++) : (x));
The double-increment is clear.
It's because you are using a macro. Since you are passing the dereferenced pointer plus the increment through the macro, the macro then puts the dereferenced pointer and the increment operation in each place y shows up in your macro. Since y shows up twice in your macro, the increment operator happens two times.
If you do the increment before you call the macro y should only be 1.

pointer & array conflict

let
int*p ,b = 5;
p = &b;
denotes a ONE DIMENSIONAL array, then what is the output given by following statement
printf("%d",p);
is it an address? if it is an address then tell me which element it belongs,please explain clearly
p = &b
This doesn't denote an array! As I explained here, they're not the same thing. b is just an integer value. If you declare b as int b[] = {1, 2, 3}; then p will point to b's first element.
printf("%d",p);
This will print p's value, and since p is a pointer and points to b, this will print b's address. printf("%d", &b); will give the same result.
By the way, if b was an array, b[5] would be translated into *(p + 5), so you can read (and write) values by adding the number of elements to the beginning of the array. And b[5] == p[5] == *(b + 5) == *(p + 5)!!! But not because arrays and pointers are the same thing, just because an array's name translates to its first element's address.
As a side note, compilers always use pointers notation (*(base + offset)) when compiling to assembly.
The p pointer does not denote a one-dimensional array. It is simply a pointer to an integer. It may point to the first element of an array, like when you do int* p = new int[6], but that's something entirely different; in that case you allocate space for a new array of six integers and you store the address of the first one (or, the beginning of the array) in p.
If you print p it will print the memory address it stores. If p "denotes an array" (emphasis on quotes) then you will print the address of the first element of the array.
int*p ,b = 5;
p = &b;
is exactly equivalent to:
int b = 5;
int *p = &b;
p ends up being a pointer to int. Now its true that this code will have much the same effect on what ends up in p (although b has a completely different type and value) as this:
int b[1] = {5};
int *p = b; // or int *p = &b[0];
certainly in either case p points to an int which you may treat as a simple int, or as the first (and only) element in a one-dimensional array of size one. So, what follows is legal and gives meaningful results in both cases:
printf("%d is stored at %p\n", *p, p);
printf("%d\n",p[0]);
but that's pretty much where the similarity ends.
address of the first element of the array. (if b was an array)
use p++ to scroll through the array

Resources