Developers struggle with C pointers because they do not feel confident. I found a very good book about it: Understanding and Using C Pointers by Richard Reese.
"Why You Should Become Proficient with Pointers
Pointers have several uses, including:
- Creating fast and efficient code
- Providing a convenient means for addressing many types of problems
- Supporting dynamic memory allocation
- Making expressions compact and succinct
- Providing the ability to pass data structures by pointer without incurring a large overhead
- Protecting data passed as a parameter to a function
Faster and more efficient code can be written because pointers are closer to the hardware.
That is, the compiler can more easily translate the operation into machine code. There is not as much overhead associated with pointers as might be present with other operators.
Many data structures are more easily implemented using pointers. For example, a linked list could be supported using either arrays or pointers.
However, pointers are easier to use and map directly to a next or previous link. An array implementation requires array indexes that are not as intuitive or as flexible as pointers."
"A solid understanding of pointers and the ability to effectively use them separates a novice C programmer from a more experienced one. Pointers pervade the language and provide much of its flexibility. They provide important support for dynamic memory allocation, are closely tied to array notation, and, when used to point to functions, add another dimension to flow control in a program.
Pointers have long been a stumbling block in learning C. The basic concept of a pointer is simple: it is a variable that stores the address of a memory location. The concept, however, quickly becomes complicated when we start applying pointer operators and try to discern their often cryptic notations. But this does not have to be the case. If we start simple and establish a firm foundation, then the advanced uses of pointers are not hard to follow and apply.
The key to comprehending pointers is understanding how memory is managed in a C program. After all, pointers contain addresses in memory. If we don’t understand how memory is organized and managed, it is difficult to understand how pointers work. To address this concern, the organization of memory is illustrated whenever it is useful to explain a pointer concept. Once you have a firm grasp of memory and the ways it can be organized, understanding pointers becomes a lot easier."
Good explanation about "Differences Between Arrays and Pointers"
There are several differences between the use of arrays and the use of pointers to arrays.
In this section, we will use the vector array and pv pointer as defined below:
int vector[5] = {1, 2, 3, 4, 5};
int *pv = vector;
The code generated by vector[i] is different from the code generated by vector+i.
The notation vector[i] generates machine code that starts at location vector, moves i positions from this location, and uses its content. The notation vector+i generates machine code that starts at location vector, adds i to the address, and then uses the contents at that address. While the result is the same, the generated machine code is different. This difference is rarely of significance to most programmers.
There is a difference when the sizeof operator is applied to an array and to a pointer to the same array. Applying the sizeof operator to vector will return 20, the number of bytes allocated to the array. Applying the sizeof operator against pv will return 4, the pointer’s size.
The pointer pv is an lvalue. An lvalue denotes the term used on the lefthand side of an assignment operator. An lvalue must be capable of being modified. An array name such as vector is not an lvalue and cannot be modified. The address assigned to an array cannot be changed . A pointer can be assigned a new value and reference a different section of memory.
Consider the following:
pv = pv + 1;
vector = vector + 1; // Syntax error
We cannot modify vector, only its contents. However, the expression vector+1 is fine, as demonstrated below:
pv = vector + 1;