Example with pointers works: Difference between * and no * at pointers?

Hello Folks,

I'm currently reading a basic c++ book and tried some example with pointers.
This example works perfect but I don't understand the explanation

In the book stands, that the variable with * (asteriks) points to the value and without the * asteriks to the address of the pointer. But with this fact, my example should print the addresses not the values?

int y[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int x[11] = {9, 8, 0,-1};

void f(int *a, size_t n){
   for ( int i = 0; i < n; i++ )
    {
       Serial.println(a[i]);
    }
    Serial.println("---------------------");
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32!");

  f(x, 10);
  f(x, 4);

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(10); // this speeds up the simulation
}

printed output

Hello, ESP32!
9
8
0
-1
0
0
0
0
0
0
---------------------
9
8
0
-1
---------------------

To print the address of a you should print it itself, not the a[i]

try this:

void f(int *a, size_t n){
  Serial.print("Address of the a: ");
  Serial.println((uint32_t) a, HEX);
  Serial.print("Values of the a[]: ");
   for ( int i = 0; i < n; i++ )
    {
       Serial.println(a[i]);
    }
    Serial.println("---------------------");
}
1 Like

consider

f: 0x116d
  0, 0x116     9
  1, 0x118     8
  2, 0x11a     7
  3, 0x11c     6
  4, 0x11e     5
  5, 0x120     4
  6, 0x122     3
  7, 0x124     2
  8, 0x126     1
  9, 0x128     0
f: 0x100d
  0, 0x100     9
  1, 0x102     8
  2, 0x104     0
  3, 0x106    -1
  4, 0x108     0
  5, 0x10a     0
  6, 0x10c     0
  7, 0x10e     0
  8, 0x110     0
  9, 0x112     0
 10, 0x114     0

int y[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int x[11] = {9, 8, 0,-1};

char s [80];

void f (
    int     *a,
    size_t   n )
{
    sprintf (s, "%s: %pd", __func__, a);
    Serial.println (s);

    for (unsigned i = 0; i < n; i++ ) {
        sprintf (s, " %2d, %p  %4d", i, & a[i], a [i]);
        Serial.println (s);
    }
}

void setup ()
{
    Serial.begin (9600);

    f (y, 10);
    f (x, 11);
}

void loop ()
{
}
1 Like

Yes. It is confusing. In the context of pointers, '*' can mean either a derefencing operator or a pointer declaration depending on where you see it.

int x[11] = {9, 8, 0,-1} ; Simple array declaration partially initialised.

void f(int *a, size_t n){ . . . declares a as a pointer to an int or, as in this case, the start of an array of the int type.

Serial.print( *x ); will print the first element in the array x[ ], that is the value 9, by dereferencing the pointer to its address.
Serial.print( *(x+1) ); will print the next element in the array x[ ] by dereferencing the pointer expression etc.

1 Like

a[n] means the same thing as *(a+n)

1 Like

This is where you have to be alert if you try to put concrete figures into the expression.
If, for example, a is at address 1024 and n is 3, the expression a+n does not necessarily result in 1027. The '+' operator is overloaded and has a new meaning. The expression is to be interpreted as a + (size of a data item) * n. In the case of a 2 byte integer a+n give 1030.

1 Like

1. Given:

byte y = 0x23;

(1) In the above declaration, the variable y refers to the 8-bit content (byte) of a RAM location of the ATmega328P MCU of the UNO Board. The range of the RAM space is: 0x0100 - 0x08EF + Stack Space (Fig-1).

ATmega328PRAMSpace
Figure-1:

(2) The symbolic name of the RAM location that holds the value of y is: Mx.
(3) Every memory location of Fig-1 has 16-bit (actually it is 12-bit) numerical value called address.

(4) The value of the address of location Mx can be known by executing the following codes:

byte *ptr; //ptr is pointer variable; it can hold address of a byte-organized memory location
ptr = &y;   //address of Mx which holds content of y is passed to ptr variable
Serial.print((uint16_t)ptr, HEX); shows 16-bit address value of Mx location; 0x08FB

2. Given:

int myData[] = {8, 9, 258, -45};

(1) In the above declaration, the array name myData (by design) contains the base address (the address of the first byte of a word (16-bit) organized array); whereas, myData[0] refers to the first byte of the M0 location (Fig-2).

ArrayWordOrganized
Figure-2:

(2) The value of the address of location M0 can be known by executing the following codes:

  int *ptr;  //ptr is pointer variable; holds base address of a word-organized memory space
  ptr = myData; //ptr holds base address of array
  Serial.println((uint16_t)ptr, HEX); //shows: 0x0100; address of M0

(3) The value of the address of location M3 can be known by executing the following codes:

  int *ptr;  //ptr is pointer variable; holds base address of a word-organized memory space
  ptr = myData; //ptr holds base address of array
  ptr = ptr + 3;  //advance pointer variable to point location M3
  Serial.println((uint16_t)ptr, HEX); //shows: 0x0106 address of M3
  Serial.println((uint16_t)*ptr, HEX); //shows: 0xFFD3; 
  //data from 16-bit wide location  M3 whose base address is in poniter variable ptr 
1 Like

Yes! They refer to the content of same memory location as verified in the context of the following declaration:

int myData[] = {8, 9, 258, -45};

ArrayWordOrganized
Figure-1:

  int *ptr;
  ptr = myData; //ptr holds base address of array
 
  Serial.println((uint16_t)myData[3], HEX); //shows: FFD3
  Serial.print((uint16_t)*(myData + 3), HEX); //shows: FFD3
  
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.