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.

#include <iostream>
int main()
{
int num = 5; //Just a regular integer variable.
char hello[] = "Hello World!"; // An array of characters.
int* point_to_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)