What is Pointer
A Pointer is a compound-type (points to other type) variable that stores whole-number, which is not other than memory addresses. An address is a particular location of an object in the memory. And the Computer-Memory is a linear collection of infinitesimal block of memory, which is 1 byte each. Each Block or Segment of memory has a particular address, starting from zero. Here, the object is an element or data or any entry in the Computer Memory. An address can tell us where the specific data is in the memory. In C, or C++, or any other programming languages, pointers are nothing but that memory address.
Pointers in CPlusPlus
We define pointer in Cplusplus by writing “*ptr”, where ptr is an identifier or name of the pointer.
[code]void *ptr=0; //pointer initialization.[/code]
in above code we declared a void pointer, and set its value, (a memory-address) is equal to zero. This is the most pure way to declare a pointer. Here, zero doesn’t mean that the pointer points to the address all the way down to zero of memory block. Technically, zero means NULL, means no value or address assigned to this pointer. NULL is a preprocessor-variable, which the cstdlib defines as 0. The most direct approach is to initialize the pointer using the literal nullptr. Therefore,
[code]void *ptr=NULL;//or, void *ptr=nullptr;[/code]
are the same. Here, void indicates the pointer can hold the address of object of any type. But, the type of the object at that address is unknown.
Void and NULL pointers
Above pointer initialization also refers to as NULL pointer, means it does not point to any Object. Code can check whether a pointer is NULL before attempting to use it. Declaring pointer as void has some limitation. With void pointer,
-we can compare it to another pointer.
-we can pass it to or return it from a function.
-and we can assign it to another void pointer.
-we can not use void pointer to operate on the object it addresses.
-we don’t know the object type, and type determines what operation we can perform on the object.
Generally, we use void pointer to deal with memory as memory, rather than using pointer to access the object stored in the memory.
WORTH MENTIONING: Uninitialized pointers are a common source of runtime error. Using uninitialized pointer in program almost always result in a runtime crash. However, debugging the resulting crashes can be surprisingly hard. So, the recommendation is to initialize all variables, and the initialization is particularly important for pointers. It is most preferable to define pointer after the object it points to. If there is no object to bind to a pointer, then initialize the pointer to nullptr or zero.
Pointer is Compound type means it refers to other type. A void pointer is a special type pointer that can hold the address of any Object.
[code]double sVar = 3.9;
void *ptr = &sVar;[/code]
[code]int sVar1 = 3;
void *ptr1 = &sVar1;
But, [except void] the type of pointer, and the object to which it points to must match.
[code]double sVar2 = 17.98;
double *ptr2 = &sVar2;//to point double object sVar2, pointer must need to be same type.
int sVar3 = 17;
int *ptr3 = &sVar3;//to point integer object sVar3, pointer must need to be integer type.
[code]int sVar3 = 78;
double *ptr3 = &sVar3;//cause an error: because, double pointer points to integer object, or, type of pointer and object differ.
So, we can see that type of pointer and object must need to match. Because, the type of the pointer is used to infer the type of the object, points to. If a pointer points to an object of another type, the operations performed on underlying object would fail.
We know that value assigned to pointers are nothing but memory addresses. So, the the value (the memory address) in a pointer can be in one of four states:
*It can point to an Object.
*It can points to the location, just immediately past the the end of an object. (void pointer)
*It can be a null pointer, indicating that it is not bound to any object.
*It can be invalid. States other than preceding three are invalid.
An error occur, when copying or try to access the value of invalid pointer. This is likely when we use an uninitialized variable, this error is one that the compiler is unlikely to detect. The result of accessing an invalid pointer is undefined. Therefore we must need to check whether a given pointer is valid.
Assignment and pointer
Both pointer and reference gives indirect access to other object. But, the difference is the way they do so. The most important is that a reference is not an object. Once we define a reference, there is no way to make that reference refer to other object. When we use reference, we always get the object – to which the reference was initially bound. On a later article we will discuss about reference in great details.
But, for pointers, there is no such identity between a pointer and the address that it holds. As with any other (non reference) variable, when we assign to a pointer, we give the pointer itself a new value. Assignment makes the pointer point to different object:
int sVar4 = 98;
void *ptr4 = 0; //pointer ptr4 is initialized, and value assigned to 0.
ptr4 = &sVar4; //value in ptr4 now changed.
//pointer ptr4 now points to address of sVar as its value.}
pointers to access object
After assigning value (memory address of an object) to pointers, we can deference it to access that object. It is possible to deference only a valid pointer that points to an object.
[code]int sVar5 = 100;
int *ptr5 = &sVar5;
*ptr5 = 10;//accessing object, sVar5 to assign a new value
std::cout << sVar5 << std::endl;//output:10
Here, when we assign 10 to *ptr5, we are assigning to the object – sVar5, which ptr5 points.
Pointers to Pointers
A pointer itself an object in the memory. Because, it holds some memory space. Any object has address in the memory, therefore, a pointer also has a memory address. Hence, we can hold or store the address of a pointer in another pointer.
We indicate each poiter level by its own operator (*). That is because we write ** for a pointer to a pointer, *** for a pointer to a pointer to a pointer, and so on.
[code]int sVar6 = 55;
int *ptr6 = &sVar6;
int **ptr7 = &ptr6;
std::cout << ptr6 << std::endl;//output: address of object » sVar.
std::cout <<ptr7 << std::endl;//output: address of pointer object » ptr6.
In this program, ptr6 points to the object – sVar6, and ptr7 is a pointer to pointer ptr6.
Arithmetic operation – like addition , subtraction of an integer to pointer means move the pointer forward or backward in an array. An integer object holds 4 byte memory space. If a pointer points to an object, it means the pointer points to the address of its first byte. Now, addition of the pointer by 1 or, incrementing, indicates the first byte of the next integer, and so on.
Subtraction of two pointers means finding their distance which is measured by elements. Bur, pointer multiplication or division is not possible.
//This is the end of general discussion on pointers. Next we will talk more about pointer arithmetic and reference in here.