By now you should be aware that C is a low-level language, and nothing shows that better than pointers. Pointers are variables that get you the variable value by "pointing" to a memory location rather than storing the value of the variable itself. This allows for some handy tricks, and is also what gives us access to arrays and file handling, among other things.
In this code, there are two declarations. The first is a typical variable initialization which creates a `double` and sets it equal to 10.1. New in our declarations is the usage of `*`. The asterisk (`*`) is usually used for multiplication, but when we use it by placing it in front of a variable it tells C that this is a pointer variable.
The next line tells the compiler where that somewhere else actually is. By using `&` in this way, it becomes the 'dereferencing operator', and returns the memory location of the variable it's looking at.
With that in mind, let's take another look at this chunk of code:
`my_pointer` has been declared, and it's been declared as a pointer. The C compiler now knows that `my_pointer` is going to point to a memory location. The next line assigns `my_pointer` a memory location value using the `&`.
Now let's take a look what referring to a memory location means for your code:
Notice that in order to get the value of the data at `*my_pointer`, you'll need to tell C that you want to get the value the variable is pointing at. Try running this code without that asterisk, and you'll be able to print the memory location, because that's what the `my_variable` variable is actually holding.
You can declare multiple pointer in a single statement as with standard variables, like so:
Notice that the `*` is required before each variable. This is because being a pointer is considered as part of the variable and not part of the datatype.
The most common application of a pointer is in an array. Arrays, which you'll read about later, allow for a group of variables. You don't actually have to deal with `*` and `&` to use arrays, but that's what they're doing behind the scenes. A commonly used array is for strings. Since strings are not defined in C, they are simply created as a character array, commonly denoted by `char * stringName;`
Sometimes you want to adjust the value of a variable inside of a function, but if you simply pass in your variable by-value, the function will work with a copy of your variable instead of the variable itself. If, instead, you pass in the pointer pointing to the memory location of the variable, you can access and modify it from outside of its normal scope. This is because you are touching the original memory location itself, allowing you to adjust something in a function and having it make changes elsewhere. In contrast to "call by value", this is called "call by reference".
The following program swaps the values of two variables inside of the dedicated `swap` function. To achieve that, the variables are passed in by reference.
The addresses, or memory locations, of `num1` and `num2` are passed to the function `swap` and are represented by the pointers `*n1` and `*n2` inside of the function. So, now the pointers `n1` and `n2` point to the addresses of `num1` and `num2` respectively.
So, now the pointer n1 and n2 points to the address of num1 and num2 respectively.
When, the value of pointers are changed, the value in the pointed memory location also changes correspondingly.
Hence, changes made to *n1 and *n2 are reflected in num1 and num2 in the main function.
### POINTERS AS PARAMETERS TO FUNCTION
when we pass any parameter to function we are making a copy of the parameter. let see with the example
```C
#include <stdio.h>
void func(int);
int main(void) {
int a = 11;
func(a);
printf("%d",a);// print 11
return 0;
}
void func(int a){
a=5
printf("%d",a);//print 5
}
```
In the example above we are changinging the value of integer a in function func, but we still geting 11 in the main function. This happens because in the function copy of integer a has passed as parameter, so in this function we have not access to the 'a' which is in main function.
So how could you change the value of integer defined in main , by using another function? Here POINTERS comes in to role.
when we supply pointer as a parameter , we have access to address of that parameter and we could to any thig with this parameter and result will be shown everywhere.
Below is an example which does exactly the same thing we want...
By dereferencing `n1` and `n2`, we now can modify the memory to which `n1` and `n2` point. This allows us to change the value of the two variables `num1` and `num2` declared in the `main` function outside of their normal scope. After the function is done, the two variables now have swapped their values, as can be seen in the output.
Whenever it can be avoided, it's a good idea to keep your code easy to read and understand. In the best case scenario, your code will tell a story- it will have easy to read variable names and make sense if you read it out loud, and you'll use the occasional comment to clarify what a line of code does.
Because of that, you should be careful when using pointers. It's easy to make something confusing for you to debug or for someone else to read. However, it is possible to do some pretty neat things with them.
Take a look at this code, which turns something from uppercase to lowercase:
```c
#include <stdio.h>
#include <ctype.h>
char *lowerCase (char *string) {
char *p = string;
while (*p) {
if (isupper(*p)) *p = tolower(*p);
p++;
}
return string;
}
```
This starts by taking a string (something you'll learn about when you get into arrays) and runs through each location. Notice the p++. This increments the pointer, which means that it is looking at the next memory location. Each letter is a memory location, so in this way the pointer is looking at every letter and deciding what to do for each one.
### Const Qualifer
The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed ( Which depends upon where const variables are stored, we may change value of const variable by using pointer ).
Above declaration is constant pointer to constant variable which means we cannot change value pointed by pointer as well as we cannot point the pointer to other variable.
A void pointer is a pointer variable declared using the reserved word in C ‘void’.
Lets illustrate this with a void pointer declaration below:
```C
void *ptr;
```
A pointer variable with the keyword `void`is a general purpose pointer variable.
The pointer can hold an address of any variable of any data type (`int`, `char`...etc).
As illustrated earlier on, the * operator serves its own purpose.
But in the case of a void pointer we need to typecast the pointer variable to dereference it mainly because a void pointer has no specific data type associated with it.
There is no other way the compiler can tell what type of data is pointed to by the void pointer.
So to take the data pointed to by a void pointer we typecast it with the correct type of the data that is held inside the void pointer's location.
Below is an example to illustrate how a void pointer coild be used in a program:
```C
#include<stdio.h>
void main() {
int a = 10;
float b = 35.75;
void *ptr; // Declaration of a void pointer
ptr = &a; // Assigning address of integer to void pointer.
printf("The value of integer variable is = %d",*( (int*) ptr) );// (int*)ptr - is ype typecasting, to point to an int type. Where as *((int*)ptr) dereferences the typecasted void pointer variable.
}
```
The output becomes
```output
The value of integer variable is = 10
```
A void pointer can be useful if the programmer is not sure about the data type of data inputted by the end user.
In such a case the programmer can use a void pointer to point to the location of the unknown data type.
The program can be set in such a way to ask the user to inform the type of data and type casting can be performed according to the information inputted by the user.
Another important point you should keep in mind about void pointers is that pointer arithmetic can not be performed in a void pointer.
Example:
```C
void *ptr;
int a;
ptr=&a;
ptr++; // This statement is invalid and will result in an error because 'ptr' is a void pointer variable.