Array:
Arrays should be familiar to everyone and are widely used.
Int A [4] = {2, 4, 5, 9 };
This statement defines an integer array a with four space sizes and initializes it.
The basic knowledge of arrays can be referred to other corresponding teaching materials. Here we mainly discuss the application of the combination of pointers and arrays.
Let's look at a complete example:
# Include <stdio. h>
Void main ()
{
Int
A [4] = {2, 4, 5, 9 };
Int * P;
P =;
* P = * P ++;
Printf ("% d
% D/N ", * P, * P + 6, * (p + 1 ));
}
Running result: 4 10 5
Analysis: The statement P = A; assigns the address of the first element of array A to the pointer P. array name a represents the address of the second element of array.
A [I] indicates the I-th element of array A. If a pointer P is defined, the statement P = & A [0]; indicates that the pointer P can be directed to the 0th elements of array A, that is, the value of P is the address of array element a [0. * (P + 1) references the content of array element a [1]. P + I is the address of array element a [I], * (p + I) references the content of array element a [I. The reference to array element a [I] can also be written as * (a + I ). It can be concluded that & A [I] And a + I have the same meaning, and P [I] And * (p + I) are also equivalent.
Although arrays and pointers have so many common features, we must remember that there is a difference between array names and pointers. The pointer is a variable, so the statements P = A and P ++ are valid. However, the array name is not a variable. Therefore, statements similar to a = P and a ++ are invalid.
Next let's look at a common function strlen (char * s)
Int strlen (char * s)
{
Int N;
For (n = 0; * s! = '/0'; s ++)
N ++;
Return N;
}
Because S is a pointer, it is legal to execute auto-increment operations on it. Executing the S ++ operation does not affect the string in the strlen function caller. It only performs auto-increment operations on the private copy of the pointer in the strlen function. In function definition, the formal parameters char s [] and char * s are equivalent.
Let's take a look at the address arithmetic operation: If P is a pointer to an element in the array, P ++ will perform an auto-increment operation on P and point to the next element, P + = I adds I to P to point to the I-th element after the current P point to the element. Like other types of variables, pointers can also be initialized. Normally, the initialization value meaningful to the pointer can only be 0 or an expression indicating the address. For the latter, the address expressed by the expression must be the address that has been previously defined with the appropriate type of data. Any comparison operation with 0 that is equal or not equal makes sense. However, arithmetic or comparative operations between pointers pointing to elements of different arrays are meaningless. Pointers can also be added or subtracted from integers. For example, P + N indicates the address of the nth object after the object pointed to by P. No matter what type P points to, the above conclusion is true. When P + N is calculated, N scales proportionally according to the length of the object pointed to by P, and the length of the object pointed to by P depends on the declaration of P. For example, if the int type occupies 4 bytes of storage space, the corresponding N in the int type calculation will be calculated by a multiple of 4.
The subtraction operation of the pointer is also meaningful. If p and q point to the elements in the same array, and P <q, q-p + 1 is the number of elements between the elements pointed to by p and q. Let's take a look at another version of strlen (char * s:
Int strlen (char * s)
{
Char
* P = s;
While (* P! = '/0 ')
P ++;
Return
P-S;
}
In the program, P is initialized to point to s, that is, to the first character of the string, the while loop statement will check each character in the string in turn, until the character '/0' at the end of the character array is met. Since P is a pointer to a character, every execution of this p ++ operation points P to the address of the next character. P-s indicates the number of checked characters, that is, the length of the string.
Conclusion: Valid pointer operations include value assignment between pointers of the same type; addition and subtraction between pointers and integers; subtraction or comparison between two pointers pointing to elements in the same array; assign a pointer to 0 or compare the pointer with 0. All other pointer operations are invalid.
Let's look at two statements: Char A [] = "I
Am a boy ";
Char * P = "I am a boy ";
A is a one-dimensional array that can only store initialization strings and null characters '/0. A single character in the array can be modified, but a always points to the same storage location. P is a pointer. Its initial value points to a String constant, which can be modified to point to other addresses. However, if you try to modify the content of a string, the result is not defined.
To better understand the relationship between arrays and pointers, let's look at a function:
Void strcpy (char * s, char * t)
{
Int I;
I = 0;
While (S [I] = T [I])! = '/0 ')
I ++;
}
Because parameters are passed through values, parameters S and T can be used in any way in the strcpy function.
The following are several versions of pointer implementation:
Void strcpy (char * s, char * t)
{
While (* s = * t )! = '/0 '){
S ++;
T ++;
}
}
Lite version:
Void strcpy (char * s, char * t)
{
While (* s ++ = * t ++)
;
}
Here, the auto-increment operations of S and T are placed in the testing part of the loop. The value of the expression * t ++ is the character T points to before the auto-increment operation is executed. The suffix operator ++ indicates that the T value is changed only after the character is read. Similarly, before S executes the auto-increment operation, the characters are stored in the old position pointed to by the pointer S. In the above version, the expression is redundant compared with '/0', because you only need to determine whether the expression value is 0.
Next, let's look at a difficult point: pointer array and pointer to pointer.
These two terms seem quite novel. What exactly do they mean?
Since pointers are also variables, they can also be stored in arrays like other variables. This is easy to understand.
Example:
# Include <stdio. h>
# Include <string. h>
Void main ()
{
Int I;
Char
B [] = {"wustrive_2008 "};
Char
* A [1];
* A = B;
For (I = 0; I <strlen (B); I ++)
Printf ("% C", * (a [0] + I ));
Printf ("/N ");
}
Running result: wustrive_2008
Here, the library function strlen and strlen are the standard library functions of the string class, so they must include # include <string. h>.
Let's write a strlen function by ourselves. Let's take the above example as follows:
# Include <stdio. h>
Int strlen (char * s)
{
Char
* P = s;
While (* P! = '/0 ')
P ++;
Return
P-S;
}
Void main ()
{
Int I;
Char
B [] = {"wustrive_2008 "};
Char
* A [1];
* A = B;
For (I = 0; I <strlen (B); I ++)
Printf ("% C", * (a [0] + I ));
Printf ("/N ");
}
The running result is the same as that in the previous example. The difference is that we implemented the strlen function, and we used the library function when programming, they are all functions written by language developers or systems for us. In fact, we can also write them by ourselves.
This example demonstrates the usage of the pointer array. The value a [1] of the pointer array is a pointer pointing to the first character of the character array.
The pointer can also be well understood, that is, the address of another pointer is put in a pointer, and the address of another pointer may point to a variable or another pointer.
Pointer and multi-dimensional array:
Let's look at two definition statements: int A [5] [10];
Int * B [5];
In terms of syntax, both a [3] [4] and B [3] [4] are legal references to an int object. But a is a real two-dimensional array, which allocates 50 int-type storage space. However, B defines that only five pointers are allocated and are not initialized. They must be initialized for display. Assume that each element of B points to an array with 10 elements, then the compiler will allocate 50 int-type storage space and 5 pointer storage space for it. An important advantage of a pointer array is that each row of the array can have different lengths. That is to say, each element of B does not have to point to a vector with 10 elements.
Pointer to the function:
In C, although a function is not a variable, a pointer to a function can be defined. Pointers of this type can be assigned values, stored in arrays, passed to functions, and returned values as functions.
If the following statement is a function parameter, what does it mean:
INT (* p) (void
*, Void *)
It indicates that p is a pointer to a function. This function has two void * type parameters and the return value type is int. In statement if (* p) (V [I], V [left]) <0), the use of P is consistent with its declaration, P is a pointer to a function. * P represents a function. If it is written as follows: int
* P (void *, void *) indicates that p is a function that returns an int pointer.
Here are two statements:
Int * F (); // F is a function that returns a pointer to the int type.
INT (* PF )();
// PF is a pointer to a function, which returns an int type object.
The above are some difficult knowledge about pointers and arrays. If you want to be familiar with them, you need to debug and think more.