-1

I'm new to pointers and I have this part of a code that I'm confused about. I have a couple of questions:

  1. In line 1, I'm not sure what the double asterisks mean. I read that it is a pointer for another pointer but I don't what that exactly.

  2. In line 4, I have no idea how to interpret the syntax:

    *(*(total_number_of_pages + x) + y)
    
/* total_number_of_pages

 * This stores the total number of pages in each book of each shelf.
 * The rows represent the shelves and the columns represent the books.
*/

int** total_number_of_pages; // (Line 1)    
int x, y; // (Line 2)    
scanf("%d %d", &x, &y); // (Line 3)    
printf("%d\n", *(*(total_number_of_pages + x) + y)); // (Line 4)
melpomene
  • 84,125
  • 8
  • 85
  • 148

3 Answers3

3

Indeed *(*(total_number_of_pages + x) + y) is hard to "grok". That is one reason the C language provides an alternative notation: *(E1 + E2) can also be written as E1[E2] (or E2[E1] since + commutes). We can apply this rule inside your expression to get: *(total_number_of_pages[x] + y) and then once again: total_number_of_pages[x][y].

This is clearer. total_number_of_pages is a pointer to the base of an array-like area of memory. total_number_of_pages[x] denotes the value of the x-th element of this. That element is itself a pointer to another array, from which [y] denotes the y-th value.

In your program, total_number_of_pages isn't given any value, which means that its use in the expression *(*(total_number_of_pages + x) + y) invokes undefined behavior. For the expression to be valid, it has to point to array of pointers which has at least x + 1 elements, and the [x] element of that array must point to an array of int which has at least y + 1 elements.

Kaz
  • 55,781
  • 9
  • 100
  • 149
0

Imagine if you had a row of books and you wanted to know how many pages were in each book in the row. You might use a collection of integers stored in consecutive memory addresses.

Now say you had many rows of books. You might use a collection of pointers to each row of books with each row of books being a collection of integers stored in consecutive memory addresses.

Since each row is a pointer, the address of the rows is a pointer to a pointer. Hence int**.

Now, total_number_of_pages is pointer to the first pointer to a row. To get to the second pointer, you'd add one to it. To get to the x'th row, you'd add x to it. If you dereference that pointer, you get a pointer to the first book in the x'th row. If you want the y'th book, you add y to it. You now have a pointer to the y'th book in the x'th row, which you dereference to get the number of pages in that book.

If you're not very familiar with pointers, you really just shouldn't try to understand code like this until you are.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

Pointers are variables that contain memory addresses. To declare a pointer variable, you just declare a regular variable using an asterisk in front of the name.

int *ptr;

I will try to explain pointers to you with some graphics and less code.

enter image description here

#include <iostream>

int main()
{
    int num = 5; //Just a regular integer variable.
    char hello[] = "Hello World!"; // An array of characters.
    int* point_to_num = &num; // & return's the memory address of a variable.
    char* point_to_hello = hello; //Notice that I don't use &. Arrays are already pointers!


    //----------Dereferencing Pointers----------//
    printf("%d\n", *point_to_num); //This will print 5

    //No Dereferencing  needed.
    printf("%s\n", hello); //This will print "Hello World!"
    printf("%s\n", point_to_hello); //This will print "Hello World!" again!

    return 0;
}

If we compare the code with the image, point_to_num is the third rectangle which contains the memory address 3000. When you dereferencing a pointer using the asterisk:

printf("%d\n", *point_to_num); //This will print 5

You are saying "Bring me the value contained in the memory address 3000"

But In this case:

printf("%s\n", hello); //This will print "Hello World!"
printf("%s\n", point_to_hello); //This will print "Hello World!" again!

strings are a sequence of characters, and you must give a pointer to the beginning of that sequence in order for printf to print the string until it finds the special null terminate character.

In your code

int** total_number_of_pages;

total_number_of_pages is uninitialized which means we can't say what the output will be.

printf("%d\n", *(*(total_number_of_pages + x) + y)); // (Line 4)
babaliaris
  • 663
  • 8
  • 16