Let's replace the word "pointer" with a datatype that's hopefully more familiar, like an int:
int n = 42;
Here 42 is an int value, and n is a variable that holds an int. You could call n an "int variable". An int is a number like 42 or -25315685, and an int variable holds these numbers. Once you have a variable you can assign different numbers to it. Nothing confusing so far?
A pointer is just like an int: a number. It happens to be a number that identifies a memory location, and if something is stored in that memory location you can call it an address. Like an int, a pointer can be stored in a variable. A variable that stores a pointer could be called a pointer variable.
So, what's the difference between a pointer and a pointer variable? The first one is a value, like a number, the second stores these values. But often people refer to variables by their values that they store; people don't call n an "int variable" but just int, even though it can at different times store different ints. In this text I'll do the same and sometimes write pointer when I mean a pointer variable; hopefully the distinction will be clear.
Is a pointer always an address? This is a question about the meaning of the word "address" more than anything else. A pointer is always an address in the sense that it corresponds to a memory location in one way or another, it's an "address" for that memory location. But on the other hand, if the memory location is not accessible to the program or doesn't have anything useful stored in it, is it really an "address" for anything?
Let's now investigate the following code:
int *p;
p = &n;
The first line declares a pointer variable called p. The pointers that can be stored into p are memory locations for int data; this is important for reasons that we'll see later. We still don't give p any value, so the pointer it stores is arbitrary. It certainly doesn't store the address of anything useful; it may even point to an area of memory inaccessible to the program.
In the second line we take the address of the n variable with the &-operator and assign it to p. Now p stores the address of n, the memory location where the value of n is stored.
What can we do with a pointer? We can read and write to the memory location that the pointer identifies. To do this we "dereference" the pointer with the *-operator, and then (*p) can be used just like you can use n. For example, you can write a new value into n with this:
*p = 123;
It's at this point that it becomes apparent why we need to know the type of data that p can point to: otherwise you can't know what you could assign to (*p).
Another reason why it's important to know the type of data that p can point to is pointer arithmetic. For example p+1 is a pointer to the int stored in memory right after n; if p was a pointer to a big data structure p+1 would be a pointer to a data structure of the same type stored right after it. For this the compiler must know the size of what the pointer points to.
Let's replace the word "pointer" with a datatype that's hopefully more familiar, like an int:
int n = 42;
Here 42 is an int value, and n is a variable that holds an int. You could call n an "int variable". An int is a number like 42 or -25315685, and an int variable holds these numbers. Once you have a variable you can assign different numbers to it. Nothing confusing so far?
A pointer is just like an int: a number. It happens to be a number that identifies a memory location, and if something is stored in that memory location you can call it an address. Like an int, a pointer can be stored in a variable. A variable that stores a pointer could be called a pointer variable.
So, what's the difference between a pointer and a pointer variable? The first one is a value, like a number, the second stores these values. But often people refer to variables by their values that they store; people don't call n an "int variable" but just int, even though it can at different times store different ints. In this text I'll do the same and sometimes write pointer when I mean a pointer variable; hopefully the distinction will be clear.
Is a pointer always an address? This is a question about the meaning of the word "address" more than anything else. A pointer is always an address in the sense that it corresponds to a memory location in one way or another, it's an "address" for that memory location. But on the other hand, if the memory location is not accessible to the program or doesn't have anything useful stored in it, is it really an "address" for anything?
Let's now investigate the following code:
int *p;
p = &n;
The first line declares a pointer variable called p. The pointers that can be stored into p are memory locations for int data; this is important for reasons that we'll see later. We still don't give p any value, so the pointer it stores is arbitrary. It certainly doesn't store the address of anything useful; it may even point to an area of memory inaccessible to the program.
In the second line we take the address of the n variable with the &-operator and assign it to p. Now p stores the address of n, the memory location where the value of n is stored.
What can we do with a pointer? We can read and write to the memory location that the pointer identifies. To do this we "dereference" the pointer with the *-operator, and then (*p) can be used just like you can use n. For example, you can write a new value into n with this:
*p = 123;
It's at this point that it becomes apparent why we need to know the type of data that p can point to: otherwise you can't know what you could assign to (*p).
Another reason why it's important to know the type of data that p can point to is pointer arithmetic. For example p+1 is a pointer to the int stored in memory right after n; if p was a pointer to a big data structure p+1 would be a pointer to a data structure of the same type stored right after it. For this the compiler must know the size of what the pointer points to.
The difference between a pointer value and a pointer variable is illustrated by:
int swap_int(int *i1, int *i2)
{
int t = *i1;
*i1 = *i2;
*i2 = t;
}
int main(void)
{
int v1 = 0;
int v2 = 37;
int *p2 = &v2;
printf("v1 = %d, v2 = %d\n", v1, v2);
swap_int(&v1, p2);
printf("v1 = %d, v2 = %d\n", v1, v2);
return 0;
}
Here, p2 is a pointer variable; it is a pointer to int. On the other hand, in the call to swap_int(), the argument &v1 is a pointer value, but it is in no sense a pointer variable (in the calling function). It is a pointer to a variable (and that variable is v1), but simply writing &v1 is not creating a pointer variable. Inside the called function, the value of the pointer &v1 is assigned to the local pointer variable i1, and the value of the pointer variable p2 is assigned to the local pointer variable i2, but that's not the same as saying &v1 is a pointer variable (because it isn't a pointer variable; it is simply a pointer value).
However, for many purposes, the distinction is blurred. People would say 'p2 is a pointer' and that's true enough; it is a pointer variable, and its value is a pointer value, and *p2 is the value of the object that p2 points to. You get the same blurring with 'v1 is an int'; it is actually an int variable and its value is an int value.
Your question is interesting in several ways, as it requires careful distinctions for several issues. But your vision seems to me to be essentially correct. I did not read your reference before writing most of this answer to avoid biasing my answer.
First, your statement Variables are symbolic names for memory
addresses, it is almost correct, but confuses the concept and its
usual implementation. A variable is actually just a container that can
contain a value that can be changed. Usually, this container is
implemented on a computer as a bock of memory space, characterized by
and address and a size since variables may contain object that
require representations with more or less information.
But I will consider mostly a more abstract point of view of the semantics of languages, independently of implementation techniques.
So variables are just containers from an abstract point of view. Such a container need not have a name. However, languages often have variables that are named by associating to it an identifier, so that uses of the variable can be expressed by the identifier. A variable can actually have several identifiers through various aliasing mechanism. A variable can also be a subpart of a larger variable: an example is a cell of an array variable, which can be named by specifying the array variable and the index of the cell, but could as well be also associated with identifiers through aliasing.
I am deliberately using the word container that is somewhat neutral, to avoid invoking other words that may be semantically loaded technically. It is actually close to the concept of reference described in wilipedia, which is often confused with a memory address. The word pointer itself is often understood as a memory address, but I do not think that is meaningful when considering most high-level languages, and probably inappropriate in the discussion paper you refer to (though addresses can be used), as it is inappropriately referring to a specific implementation. However, it is appropriate for a language like C, which is supposed to be much closer to implementation concepts and the machine architecture.
Actually, if you look at variables or values at the implementation level, there may be several complex systems of indirection, of "machine level pointers", but that are (and should be) invisible to the user, so that the abstract point of view I develop can be valid. For most programming languages, the user should not have to worry, or even know, about implementation, as implementation can vary a lot for a given language. This may not be true for some languages, such as C, that are intentionally close to the machine architecture, as an advanced substitute for assembly languages that are in almost direct relation to explicit binary coding, but far too low level for convenient use in most situations.
What the user of a language should know, and sometimes it should be even less than that, is what are values and associated operations, where they can be contained, how they can be associated to names, how the naming system works, how can new kinds of values be defined, etc.
So another important concept is identifiers and naming. Naming an entity (a value) can be done by associating an identifier with a value (usually in a declaration). But a value can also be obtained by applying operations to other named values. Names can be reused, and there are rules (scoping rules) to determine what is associated to a given identifier, according to context of use. There are also special names, called litterals, to name the values of some domains, such as integers (e.g. 612) or boolean (e.g. true).
The association of an unchanging value with an identifier is usually called a constant. Litterals are constants in that sense.
"Value containers" can also be considered as values, and their association with an identifier is a variable in the usual "naive" sense that you have been using. So you might say that a variable is a "container constant".
Now you might wonder what is the difference between associating an identifier with a value (constant declaration) or assigning a value to a variable, i.e. storing the value in the container defined as a container constant. Essentially, declaration may be seen as an operation that defines a notation, that associate an identifier which is a syntactic entity to some value which is a semantic entity. Assignment is a purely semantics operation that modifies a state, i.e. modifies the value of a container. In some sense, declaration is a meta concept with no semantic effect, other than providing a naming (i.e. syntactic) mechanism for semantics entities.
Actually, assignments are semantic operations that occur dynamically as the program is executed, while declarations have a more syntactic nature and are usually to be interpreted in the text of the program, independently of execution. This is why static scoping (i.e. textual scoping) is usually the natural way to understand the meaning of identifiers.
After all this, I can say that a pointer value is just another name for a container,and a pointer variable is a container variable, i.e. a container (constant) that can contain another container (with possible limitations on the containing game imposed by some type system).
Regarding code, you state [pointers] might indicate the entry point
to a section of code and can be used to call that code. Actually this
is not quite true. A section of code is often meaningless alone
(from high level or implementation point of view). From a high-level
point of view, code usually contains identifiers, and you have to
interpret these identifiers in the static context where they were
declared. But there is actually a possible duplication of the same
static context, due essentially to recursion which is a dynamic
(run-time) phenomenon, and the code can only be executed in an
appropriate dynamic instance of the static context. This is a bit
complex, but the consequence is that the proper concept is that of a
closure that associate a piece of code and an environment where the
identifiers are to be interpreted. The closure is the proper semantic
concept, i.e. is a properly definable semantic value. Then you can
have closure constants, closure variables, and pointers to closures,
which are containers that can contain another container containing a
closure.
A function is a closure, usually with some parameters to define or initialise some of its entities (constants and variables).
I am skipping many variations on the uses of these mechanisms.
Closures can be used to define OO structures in imperative or functional languages. Actually, early work on OO style (probably before the name) was done that way.
The paper you reference, which I skimmed quickly, seems to be an interesting one, written by a competent person, but possibly not an easy reading if you do not have significant experience with a variety of languages and their underlying computational models.
But remember: many things are in the eyes of the beholder, as long as he preserves a consistent view. Points of view may differ.
Does this answer your question?
PS: This is a long answer. If you consider some part of it inadequate, please be explicit about which it is. Thank you.
The difference is by definition and application, a pointer is a specialized variable to hold a memory address of another variable; in OO terms a pointer would perhaps be considered to inherit its behavior from a general class called variable.
Difference between setting a variable, and setting a pointer
What is the difference between a pointer variable and simply storing an address in a variable?
Pointers vs Variables - Talk - GameDev.tv
C: Whats the difference between pointer = variable and pointer = &variable? - Stack Overflow
Videos
Take the example
int num = 40; int ptr1 = # int* ptr2 = # //both output the same hex
Does the programming language treat * declared pointers differently than variables defined as memory addresses?
Whoever explained this to you is wrong in this case:
#include <stdio.h>
int main() {
int a = 5; //variable a has value 5 put it
//a does have an address
int b = a;
//variable b is created, it has its own seperate memory address.
//in this case the CONTENTS of a (5) are dumped inside b
return 0;
}
saying int b=a; will not make the variables aliases of each other.
What you heard about is this:
//...
int a=1;
int *b = &a; //create a pointer called b and make it point to a
//(set it equal to address of a)
in your case you have:
memory addresses: variable name value stored at memory address
1000 a(int) 5
1004 b(int) 5
obviously changing values of a and does not affect each other
in the case I described you have this:
memory addresses: variable name value stored at memory address
1000 a(int) 5
1004 b(int*) 1000
as you can see, since b is a pointer, its actual value is the address of a.
so doing *b=3; will change the value of a
When you declare
int a = 1;
Compiler allocate memory for sizeof(int) bytes and name that data location (or memory block) a and place a value 1 in that block.
In a very simple way a variable is a named location of data.
You can think of it as putting the value assigned in a box with the variable name as shown below:

And for all the variables you create a new box is created with the variable name to hold the value.
Assigning one variable to another makes a copy of the value and put that value in the new box.
a = 2;
int b = a;

So, a and b are not pointers but are the names of different memory blocks having their own addresses.
don't they both access the memory address of a variable? if so, then what's the difference between them? and when can i use them? like can i obtain and print the address of a variable without using the pointer? or can i obtain the adress of a variable without using the amperstand?