Greetings,
Pointers are facile, yet confusing. Thinking in the programming world isn’t easy, and comprehending everything read, intricate. This tutorial leads from the previous, which may clarify many doubts in the previous segment.
You have learned most, if not all, of the basics pertaining pointers in the previous tutorial. Here, we’ll discuss the fact-finding situations of pointers and their importance in the programming world. This tutorial is to help you understand pointers in application, how to dissect them, and how to use them properly.
Pointer arithmetic is also a crucial segment of learning pointers in their entirety. I briefly covered this subject in the previous tutorial, which will indeed lead to a more successful approach in pointer utilization in the near future.
Pointers in application
Fully understanding pointers will further help you when you run into a problem, or become confused in your current program or project. For our first approach, lets further explain the pointer usage:
int main() {
char ch[25];
char *p;
p = &ch[0];
strcpy(p, “Test);
memcpy(&p[4], “ing, 3);
p[7] = '\0';
return 0;
}
Example 1.1: Utilizing pointers in a new view
That may seem weird, though all functions that retrieve a pointer point to where you send. Normally when you send a pointer, you don’t send its address. Since the function prototype asks for a single pointer, you send it the pointer. If we were to dissect the memcpy function, we may notice the first parameter looks different; at least while normal variable names were sent. Functions like memcpy() take a one-dimensional character array in one or more of their arguments.
We are aware that the & operator only applies to objects in memory. Also previously learned is that p points to ch; no matter which is changed, they both correspond. Also, we are aware of the fact that “p[4] is a single character from our array. In the cataclysmic event, we are complying with the one-dimensional array as to this extent: We are sending the object p at position 4. Any changes to this variable will proceed with and after position 4.
If we were to take a more in-depth look, this is how the compiler perceives this: The & operator takes a one-dimensional array and then deals with the memory address; causing a “char * to be perceived as a “char **. Likewise with our object “p. p[4] is a character. The & operator will then make our “char look like a “char *. Since we defined which location to start at “[4], our new “char * will start at position 4 when converted.
Another Example:
int myFunc(int *);
int main() {
int i = 3;
int j = 2;
int *k;
k = &j;
myFunc(&i); // i isn’t a pointer, so send variable address
myFunc(k); // k points to j, k is already a pointer; don’t send address
return 0;
}
int myFunc(int *x) {
int z = *x;
return z;
}
Example 1.2: When to send a memory address
It is pertinent to know when and when not to send a pointer address to a function. For example, as we just saw above, consider the following:
#include <stdio.h>
int main() {
char ch[25];
char *p;
p = &ch[0];
scanf(“%s, &p); // incorrect
// same reason why
fgets(&p, 24, stdin); // is incorrect
// don’t send pointer address to either since p is already a pointer.
return 0;
}
Example 1.3: Pointers address information not always needed.
Same applies for non-pointers in this case. The character array/pointer already contains an address, and when sending to a function, don’t send the address of unless you send the location. Many don’t understand why it isn’t appropriate to send the address of a character array to scanf(). It is simple actually. The reason we don’t send it is because we want to write to its data, not its address. The reason we do send it when dealing with an integer, float, double, or other is because scanf() takes pointers to objects. If you want to store the result on a standard variable, it is imperative to precede it with the reference operator.
Another Example:
#include <stdio.h>
int main() {
char ch[25];
char *p;
p = &ch[0];
scanf(“%s, &p[0]); // correct; send address point ([0])
// Or
fgets(&p[0], 24, stdin);
return 0;
}
Example 1.4: Send pointer address including where to point to
This way, scanf() can write to p, not the address. The address is good when you need to directly gain access to a variable, though here we don’t need to.
Integer variables see otherwise. When sending information to a function that needs access, it usually means it wants the address too, like scanf(). Remember, sending address information is completely different when dealing with an array or not. The difference is very obvious:
int main() {
int i, j[2];
int *p, *q;
p = &i;
q = &j[0];
*p = 3; // i = 3
*++(q) = 1; // j[1] = 1
return 0;
}
Example 1.5: Integers, and the difference between array’s and non-array’s
There is a large difference between integers and character arrays. Expounding on this seems nagging, though it is what most programmers need to understand. The integer array is controlled by indices. My array[0] is a number, then my array[1] is another number. They are handled separately, and require more hand-holding. The character array is different, you have an array, and it controls the whole block. No need to set one array index at a time.
Pointer Techniques
Pointers can be used in many programs, varying from the instance. You can use them to allocate memory, point to other variables, change data from a specified address, and so on and so forth. It really depends on where you use them, and what they are being used for. For example, if you wanted to send a two-dimensional array to a function and allocate it there; it would be somewhat impossible to send the 2-D pointer and memory address and allocate it there. There are ways around this though, for instance we would send our 2-D pointer to a function. Then we would create a temporary 2-D pointer inside our separate function and allocate it there. Tell our sent object to equal the temporary variable, and we are on our way.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
void alloc2D(char ***, int, int);
int main() {
int i;
char **string;
alloc2D(&string, 3, 5);
// Free memory
for (i = 0; i < 3; i++)
free(string[i]);
free(string);
return 0;
}
void alloc2D(char ***str, int row, int column) {
int i;
char **temp;
temp = (char **)malloc(row * sizeof(*temp));
if (temp)
for (i = 0; i < row; i++)
temp[i] = (char *)malloc(column * sizeof(**temp));
*str = temp; // Object of str now links to temp
}
Example 1.6: Allocating a 2-dimensional array by passing pointers.
Conclusion
In conclusion of this segment, there are many ways pointers can be utilized in programs. This tutorial is just here to provide information on pointers, and how they work. With the fundamentals, it should not be difficult to debug your own programs and figure out why they may be performing as so.
This tutorial is short as I tried to retain the brevity of the previous tutorial. Pointers in application is not a big issue, as there are many ways of utilizing them, and is not well served by alot of examples. My short explanations are powerful, and most of the answers lie within. I hope this information has helped you learn and disect pointers to the next step.
- Stack Overflow