Pointer to object#
Object#
For example:
int number = 42;
char name[] = "Partha";
- numberis the identifier of the object- 42.- 42is stored in an data storage area of 4 bytes.
- nameis the identifier of the object- "Partha". This object consists of 7 characters.
We used pointers before#
Remember the following diagram from section Arguments and return value in functions:
        flowchart LR
  x[argument/s]:::dashed <--> B[function]
  B -- return value --> y:::hidden
  classDef hidden display: none;
  classDef dashed stroke-dasharray:5;
    Do you remember
- what the arrow tips (directions) mean? 
- an example where a function writes to its arguments? 
Meaning#
Fig. 21 A pointer variable a which has the value 1008. 1008 is an address. If we dereference a, we get the value of the variable b.#
Source CC-BY-SA 3.0 Unported by User:Sven
Example:
#include <stdio.h>
int main() {
  int b = 42;
  int *a = &b;
  printf(" b: %d\n", b);
  printf("&b: %p\n", &b);
  puts("");
  printf(" a: %p\n", a);
  printf("*a: %d\n", *a);
  printf("&a: %p\n", &a);
}
 b: 42
&b: 0x7ffdca90d08c
 a: 0x7ffdca90d08c
*a: 42
&a: 0x7ffdca90d080
Declaration#
int *a;  // Pointer to an `int`
char *c;  // Pointer to a `char`
int **d; // Pointer to a pointer to an `int`
float *e = nullptr; // Initialization with zero 
                    // Better than `0`, because `nullptr` identifier shows intent
Usage#
| Operator | Meaning | Example | 
|---|---|---|
| 
 | dereference | 
 | 
| 
 | address of | 
 | 
Activity 42 (Meaning of pointer operators)
Which are correct for the code above?
- a == 42
- *a == 42
- &a == 42
- &*b == 42
- *&b == 42
Activity 43 (Declaring and using a pointer)
Code the following:
- Declare and initialize an - unsignednumber called- n.
- Declare and initialize a pointer to - ncalled- p1.
- Declare and initialize a pointer to - ncalled- p2.
- Print the value that - p1points to.
- Increment - n.
- Print the value that - p2points to.
What are printed values?
Arrays can be used as pointers#
#include <stdio.h>
char msg[] = "Welcome!";
int main() {
  printf(" msg[0]: %c\n", msg[0]);
  printf(" msg: %p\n", msg);
  printf("*msg: %c\n", *msg);
  puts("");
  printf(" msg[1]: %c\n", msg[1]);
  printf(" msg + 1: %p\n", msg + 1);
  printf("*(msg + 1): %c\n", *(msg + 1));
}
 msg[0]: W
 msg: 0x570edd076020
*msg: W
 msg[1]: e
 msg + 1: 0x570edd076021
*(msg + 1): e
We observe:
- msg[1]gives the same value as- *(msg + 1).
Note that we can do pointer arithmetic like we do with other types.
We repeat our experiment with an int array:
#include <stdio.h>
int moves[] = {3, 0, 2, 8};
int main() {
  printf(" moves[0]: %d\n", moves[0]);
  printf(" moves: %p\n", moves);
  printf("*moves: %d\n", *moves);
  puts("");
  printf(" moves[1]: %d\n", moves[1]);
  printf(" moves + 1: %p\n", moves + 1);
  printf("*(moves + 1): %d\n", *(moves + 1));
}
 moves[0]: 3
 moves: 0x55e8bb743020
*moves: 3
 moves[1]: 0
 moves + 1: 0x55e8bb743024
*(moves + 1): 0
Activity 44  (Pointer arithmetic with char vs int)
Something is odd. We added 1 to the pointer but the address increased by four 😮. What could be the reason?
Hint
What is sizeof(int)?
Activity 45  (Calculating pointer + n)
- What would be the difference if you use a - double? Guess and check your answer by modifying the code above.
- Can you write a general formula for - pointer + non the paper using (1) the size of the data type and (2) address stored in the- pointer?
Pointers can be used as arrays#
#include <stdio.h>
char msg[] = "Welcome!";
char *sptr = msg;
// same as
// char *sptr = "Welcome";
int main() {
  printf("  sptr[0]: %c\n", sptr[0]);
  printf("  sptr: %p\n", sptr);
  printf(" *sptr: %c\n", *sptr);
  puts("");
  printf("  sptr[1]: %c\n", sptr[1]);
  printf("  sptr + 1: %p\n", sptr + 1);
  printf("*(sptr + 1): %c\n", *(sptr + 1));
  puts("");
  puts("using an array vs a pointer to access:");
  printf(" msg[10]: %c\n", msg[10]);
  // Compiler warns that 10 is past the end of array
  printf(" sptr[10]: %c\n", sptr[10]);
  // No warning, you can do whatever do want
  // For example sptr[10000000] leads to a segmentation fault
}
sptr[0]: W sptr: 0x5c16a679e020 *sptr: W sptr[1]: e sptr + 1: 0x5c16a679e021 *(sptr + 1): e using an array vs a pointer to access: msg[10]: sptr[10]:
Pointer does not know its boundaries if used as an array, but an array variable does.
Pass by address vs pass by value#
void set_to_42(int *n);  // pass by address
void set_to_58(int n);  // pass by value. Value is copied and given to the function
- pass by value
- the value of the argument is bound to the corresponding variable in the function typically by copying the value into a new memory region. 
Activity 46 (Pass by address vs value using scalar values and array)
- Implement the functions above in using the following template and use them. 
- Guess the output before you run your program. 
#include <stdio.h>
void set_to_42(int *n) {
  // YOUR CODE HERE
}
void set_to_58(int n) {
  // YOUR CODE HERE
}
void set_first_element_to_58(int *arr) { // Same as int arr[]
  // YOUR CODE HERE
}
int main() {
  int n;
  int arr[10];
  // Use the first function
  // YOUR CODE HERE
  printf("n: %d\n", n);
  // Use the second function
  // YOUR CODE HERE
  printf("n: %d\n", n);
  // Use the third function
  // YOUR CODE HERE
  printf("arr[0]: %d\n", arr[0]);
}
Warning
The following argument which tries to get a pointer to the array does not make sense. An array is passed as an address anyway.
void set_first_element_to_42(int *arr[])
Note
In literature, you will also see the term pass by reference instead of pass by address. A reference in C is always an address and an address is always a pointer.
When you talk about it, use pass by reference and pass by value – every C programmer will understand it. One stands for having remote access and the other for copying the data.
However if you dig deeper, then you see that in C everything is pass by value, because the pointers are copied when a function is executed. But it is more important how objects are modified/copied and not pointers themselves.
Copying an array for passing-by-value#
Arrays are always passed by reference to functions. To create a passing-by-value effect, we have to copy it:
Programming the analogy from Activity 41.
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#define WIDTH 5
typedef enum { EMPTY, SENTENCE, PHOTO, BOTH } collage_t[WIDTH];
collage_t collage;
/**
 * Wants only to write something on the first empty slot
 */
void sentence_friend(collage_t collage) {
  for (size_t col = 0; col < WIDTH; ++col)
    if (collage[col] == EMPTY) {
      collage[col] = SENTENCE;
      return;
    }
}
/**
 * picks a random place and puts both a sentence and a photo.
 */
void creative_friend(collage_t collage) {
  for (size_t tries = 0; tries < WIDTH; ++tries) {
    size_t col = rand() % WIDTH;
    if (collage[col] == EMPTY) {
      collage[col] = BOTH;
      return;
    }
  }
}
/**
 * Careless friend just overwrites
 */
void careless_friend(collage_t collage) { collage[rand() % WIDTH] = PHOTO; }
int main() {
  // FOR DEMO: use debugger to visualize the changes
  sentence_friend(collage);
  creative_friend(collage);
  // You copy the collage for the careless friend
  collage_t collage_copy;
  for (size_t col = 0; col < WIDTH; ++col)
    collage_copy[col] = collage[col];
  careless_friend(collage_copy);
  // Then you merge the collage_copy into the collage.
}
Why did we not copy the array inside of careless_friend? Because then the storage area will not be available.
