Here are the most powerful features of C language, but also relatively difficult to grasp one of the concepts-pointers.
First, the basic concept of pointers
Like other basic types of variables, a pointer is a variable, but it is a variable that takes a memory address as its value. Because pointers usually contain the address of a variable that has a specific value, it can indirectly refer to a value.
Declaration, initialization, and operators of pointer variables
Declaration statement
int *ptra, a;
Declared an integer variable A and a pointer to an integer value, that is, the use of * (referred to as the "indirect reference operator") in a declaration statement indicates that the variable being declared is a pointer. Ptra Pointers can be declared to point to any data type. It should be emphasized that in this statement variable A is declared only as an integer variable, because the indirect reference operator * is not for all variables in a declaration statement, so each pointer must precede its name with a prefix * declaration. The pointer should be initialized with a declaration statement or an assignment statement. You can initialize the pointer to 0, NULL, or an address, and a pointer with a value of 0 or null does not point to any value, but to assign a variable address to the pointer, use the single order operator & (called the "Address Operator").
For example, a program has used a declaration statement
int *ptra, a=3;
Declared integer variable A (value 3) and pointer A to an integer value, then the assignment statement
ptra=&a;
You can assign the address of variable A to the pointer variable Ptra. Note that operator & cannot be used on variables that are declared as register for constants, expressions, or storage categories. The assigned pointer can get the value of the object it points to by using the operator *, which is called a "duplicate reference to the pointer", such as a print statement
printf("%d", *ptra);
It prints out the value of the object (that is, the value of a) that the pointer variable Ptra points to 3. If the referenced pointer is not properly initialized or does not point to a specific memory unit, it can result in fatal execution errors or accidental modification of important data. printf's conversion specifier%p the memory address as a hexadecimal integer, for example, after the above assignment, the print statement
printf("%p", &a);
printf("%p", ptra);
Will print out the address of variable A.
Three, pointer expressions and arithmetic operations, and the relationship of arrays, strings, and pointers
In arithmetic expressions, assignment expressions, and comparison expressions, pointers are legitimate operands, but not all operators are legitimate when used with pointer variables, and the limited arithmetic operations that can be performed on pointers include self augmentation (+ +), self subtraction (--), plus an integer (+, + =), Subtract an integer (-or-=) and subtract another pointer.
The elements of an array are stored continuously in memory, which is the basis of pointer operations. Now suppose that on a machine with an integer of 4 bytes, pointer ptr is initialized to the element a[0 of integer array A (a total of three elements), and A[0] 's address is 40000, the address of each variable is shown in the following table:
An expression |
Ptra |
&A[0] |
&A[1] |
&A[2] |
The meaning of an expression |
Value of pointer Ptra |
The address of the element a[0] |
The address of the element a[1] |
The address of the element a[2] |
The value of an expression |
40000 |
40000 |
40004 |
40008 |
It is important to note that pointer operations are different from regular arithmetic operations, and generally the result of a 40000+2 is 40002, but when a pointer adds or subtracts an integer, the pointer is not simply adding or subtracting the integer value, but adding the integer to the size of the pointer reference object. And the size of the object is related to the machine's data type with the object. For example, in the above case, the statement
ptra+=2;
The result is 40000+4*2=40008, and Ptra also points to the element a[2], and similarly, such as statements
ptra-=2;
ptra++;
++ptra;
ptra--;
ptra--;
And so on the same principle of operation, as for the pointer and pointer subtraction, you will get the number of elements contained in the two addresses, such as PTRA1 contains storage unit 40008,PTRA2 contains storage unit 40000, then the statement
x = ptra1 - ptra2;
The result is 2 (still assuming that the integer is in memory for 4 bytes). Because we cannot assume that two variables of the same type are stored continuously in memory except for the array elements, the pointer arithmetic operation has no meaning except for the array.
If the two pointer types are the same, you can assign a pointer to another pointer, or you must use the coercion type conversion operator to convert the type of the pointer to the right of the assignment operator to the type of the pointer to the left of the assignment operator. For example, PTR1 is a pointer to an integer, and ptr2 is a pointer to a floating-point number, then the value of PTR2 is assigned to PTR1, the statement
ptr1 = (int *) ptr2;
To achieve. The only exception is a pointer to a void type (that is, void *), because it can represent any type of pointer. Any type of pointer can be assigned to a pointer to a void type, and a pointer to a void type can also be assigned to any type of pointer, neither of which requires the use of coercion type conversions.
However, because the compiler cannot determine the number of bytes of a pointer to a void type based on the type, the duplicate reference void * Pointer is a syntax error.
You can compare two pointers with the equality test operators and relational operators, but this comparison is generally meaningless unless they point to elements in the same array. The equality test operator is generally used to determine whether a pointer is null, which is useful in memory operations later in this article.
The array in C language has a close relationship with the pointer, they can be almost interchangeable, in fact the array name can be considered as a constant pointer, assuming that a is an array of integers with five elements, and that the assignment statement
ptra = a;
Assigning the address of the first element to a pointer ptra to an integer, the following set of expressions is equivalent:
A[3] ptra[3] * (ptra+3) * (a+3)
They all represent the value of the fourth element in the array.
And because the string in C is a character array that ends with a null character (' "), the fact is that a string is a pointer to its first character. But let's remind you that array names and string names are constant pointers, and their values are immutable, such as program segments
char s[]="this is a test.";
for (;*s='\0';s++)
printf("%c", *s);
Is wrong because it tries to change the value of s in the loop, and S is actually a constant pointer.
At the end of this section, say a pointer to a function. A pointer to a function contains the address of the function in memory, which is actually the starting address in memory of the code that completes the function task. function pointers are commonly used in menu-driven systems.