C language basics - (the origin of C language - pointer)

Comments from friends are welcome✨✨ This chapter series is a deep thinking and summary of C language, and the content of C language will continue to be updated


foreword

Pointer is an important concept in C language, and it is also an important feature of C language. Using it correctly and flexibly can make the program concise, compact and efficient. Everyone who learns and uses C language should learn and master pointers in depth. It can be said that not mastering pointers means not mastering the essence of C.
The concept of pointers is relatively complicated, and its use is relatively flexible, so beginners often make mistakes. Please be very careful when studying the content of this chapter, think more, compare more, use more computers, and master it in practice.


1. What is a pointer?

In order to clarify what a pointer is, you must first figure out how data is stored in memory and how to read it.
If a variable is defined in the program, the system will allocate memory units to the variable when the program is compiled.
The compilation system allocates a certain length of space according to the variable type defined in the program. Each byte in the memory area has a number , which is the address , which is equivalent to the room number in the hotel. The data stored in the memory unit marked by the address is equivalent to the passenger living in the hotel room.
Since the desired variable unit can be found through the address, it can be said that the address points to the variable unit . For example, a room number 2008 is hung on the door of a room, and this 2008 is the address of the room, or in other words, 2008 points to the room. Therefore, the address is visually called a pointer . It means that the memory unit with its address can be found through it.

Explanation: The access to the computer storage unit is more complicated than that of the hotel. In the C language, the data is divided into types. For different types of data, the size of the storage unit (number of bytes) and the storage method allocated in the memory are different. (For example, integers are stored in complement form, and real numbers are stored in exponential form). If you only specify the address 1010 and want to call out data from this unit, this is impossible. Although the specified storage unit can be found, it is impossible to determine whether to fetch information (character data) from 1 byte. Or get information from 2 bytes (short integer), or get information from 4 bytes (integer). There is also no description of the storage method used to access data (integer and single-precision real numbers are both 4 bytes, but the storage methods are different). Therefore, in order to effectively access a piece of data, in addition to the location information, the type information of the data is also required (if there is no type information of the data, only the location information cannot access the data). The address in C language includes location information (memory number, or pure address) and the type information of the data it points to, or it is a typed address such as &a, which is generally called the address of variable a , to be precise , which is the address of the integer variable a . The addresses mentioned later all mean this.

Please be sure to understand the difference between the two concepts of the address and the content . Suppose the program has defined 3 integer variables i, j, k. When the program is compiled, the system may assign the address 2000 ~ 2003 4 bytes for variable i, 2004 ~ 2007, 4 bytes for j, 2008 ~ 2011 4 bytes for k (different compilation systems in different compilations, the address of the storage unit assigned to the variable are not the same), in the program, the value of the variable is generally referred to by the variable name, for example:
printf("%d\n",i);
Since the system has allocated integer storage for the variable i during compilation The 4 bytes of the method, and the corresponding table of the variable name and address is established, so when executing the above statement, first find the corresponding address through the variable name, and read the integer from the 4 bytes according to the storage method of the integer data The value of variable i is then output in decimal integer format.
Note: Access to variables is done by address.
If there is an input statement
scanf("%d",&i);
during execution, the value entered by the keyboard is sent to the integer storage unit whose address starts from 2000. If there is a statement
k = i + j;
then take out the value of i from 2000 ~ 2003 bytes (3), and then take out the value of j from 2004 ~ 2007 bytes (6), add them together and then sum them (9 ) to the 2008 ~ 2011 byte units occupied by k.
This kind of access directly by variable name is called direct access .
You can also use another method called indirect accessThe method is to store the address of variable i in another variable, and then find the address of variable i through this variable, so as to access variable i.
In the C language program, you can define integer variables, floating-point (real) variables, character variables, etc., and you can also define a special variable and use it to store addresses. If a variable i_pointer is defined (the variable name can be chosen arbitrarily), it is used to store the address of the integer variable. The address of i (2000) can be stored in i_pointer by the following statement.
i_pointer = &i ; //Store the address of i into i_pointer
At this time, the value of i_pointer is 2000 (that is, the starting address of the unit occupied by variable i).
To access the value of variable i, you can use direct access or indirect access: first find the variable i_pointer that stores the address of variable take out
the address of i (2000) from it, and then start at 2000 bytes Access the value of i in the memory location of . The pointing
of the pointer is reflected by the address. Assuming that the value in i_pointer is the address of variable i (2000), a connection is established between i_pointer and variable i, that is, the address of i can be known through i_pointer, and the memory unit of variable i can be found. Since the required variable unit can be found through the address, it is said that the address points to the variable unit (like a room number points to a certain room). Visualize addresses as pointers
. It means that the memory unit with its address can be found through it (just as the storage unit of variable i can be found according to the address 2000).
If there is a variable specially used to store the address of another variable (that is, a pointer), it is called a pointer variable . The above i_pointer is a pointer variable. The pointer variable is the address variable, which is used to store the address, and the value of the pointer variable is the address (that is, the pointer).

Note: Distinguish between the two concepts of pointer and pointer variable. For example, it can be said that the pointer of the variable i is 2000, but it cannot be said that the pointer variable of i is 2000,
the pointer is an address, and the pointer variable is a variable that stores the address.

2. Pointer variable

2.1. How to define pointer variables

The general form of defining a pointer variable is
type name * pointer variable name;
such as:
int *pointer_1, *pointer_2;
the int at the left end is the base . The base type of a pointer variable is used to specify the type of variable that this pointer variable can point to.

Explanation: The basic data types (such as int, char, float, etc.) have been introduced earlier. Since there are variables of these types, there can be pointers to these types of variables. Therefore, pointer variables are derived from basic data types. It cannot exist independently without the basic data type.

The following are legal definitions:
float *pointer_3; // pointer_3 is a pointer variable pointing to a float variable, referred to as a float pointer
char *pointer_4; // pointer_4 is a pointer variable pointing to a character variable, referred to as a char pointer
You can define pointer variables , initialize it at the same time, such as:
int *pointer_1 = &a , *pointer_2 = &b ; // define pointer variables pointer_1 , pointer_2 , and point to a , b respectively

Note: Pay attention when defining pointer variables:
(1) The ✳ in front of the pointer variable indicates that the variable is a pointer variable. The pointer variable names are pointer_1 and pointer_2, not ✳pointer_1, ✳pointer_2.
This is different from defining integer or real variables.
(2) When defining a pointer variable, the base type must be specified , and it must be known that different types of data occupy different bytes and storage methods in memory. Pointing to an integer variable and pointing to a real variable have different physical meanings. From another perspective, the pointer variable is used to store the address, and the address information of C includes the location (memory number) and type information of the storage unit. The properties of the pointer variable should match it. For example:
int a , ✳p ;
p = &a ;
&a not only includes the location of variable a (such as the storage unit numbered 2000), but also includes the information that the stored data is an integer. Now define the base type of the pointer variable p as int, that is, what it points to can only be integer data. At this time p can receive the information of &a. If it is changed to
float ✳p ;
p = &a ;
&a is the address of the integer variable a , a warning will appear at compile time:
convert an int * type data to float * data . When assigning a value, the compilation system will automatically change the base type of &a to float type, and then assign it to p. But p cannot use this address to point to an integer variable.
From the above, we can know that the pointer or address contains type information. You should make the types on both sides of the assignment number consistent to avoid unexpected results.
The meaning of a variable pointer includes two aspects, one is the pure address expressed by the storage unit number (such as the number is 2000), and the other is the data type of the storage unit it points to (such as int, char, float, etc.).
(3) How to represent the pointer type. The pointer type to integer data is denoted as int *, read as pointer to int or simply int pointer.

(4) Only the address (pointer) can be stored in the pointer variable, do not assign an integer to a pointer variable. For example:
pointer_1 = 100; // pointer_1 is a pointer variable, and 100 is an integer, which is illegal. The original
intention is to assign the address 100 to the pointer variable pointer_1, but the system cannot distinguish it as an address. From the formal point of view, 100 is an integer constant, and the integer Constants can only be assigned to integer variables, but not to pointer variables, which is considered illegal. In the program, a value cannot be used to represent the address, the address can only be obtained by the address symbol & and assigned to a pointer variable, such as p = &a;

2.2 How to reference pointer variables

When referring to a pointer variable, there may be 3 situations:
(1) Assign a value to the pointer variable. Such as:
p = &a ; // Assign the address of a to the pointer variable p.
The value of the pointer variable p is the address of the variable a, and p points to a.

(2) Refers to the variable pointed to by the pointer variable.

If p = &a ; has been executed , that is, the pointer variable p points to the integer variable a, then the function
of printf(" %d ", *p);
is to output the value of the variable pointed to by the pointer variable p in the form of an integer, that is, the variable the value of a.
If there is the following assignment statement:
*p = 1;
means to assign the integer 1 to the variable currently pointed to by p, if p points to the variable a, it is equivalent to assigning 1 to a, that is, a = 1 ; .
(3) Reference the value of the pointer variable. For example:
printf(“%o”, p);
the function is to output the value of the pointer variable p in the form of octal number, if p points to a, it is to output the address of a, ie &a.
Note: To be proficient in the two related operators.
(1) & Take address operator. &a is the address of variable a.
(2) * Pointer operator (or indirect access operator), *p represents the object pointed to by the pointer variable p.

2.3. Pointer variables as function parameters

The parameters of the function can not only be data such as integer, floating point, character, etc., but also can be a pointer type. Its role is to transfer the address of a variable to another function.
In order to make the variable value changed in the function be used by the calling function main, the pointer variable should be used as the function parameter. During the execution of the function, the variable value pointed to by the pointer variable changes. After the function call ends, the variable value The change is still retained, so that the value of the variable is changed by calling the function, and these changed values ​​can be used in the calling function (such as the main function).
If you want to get n values ​​to be changed through function calls, you can do this:
① Set n variables in the calling function, and use n pointer variables to point to them;
② Design a function with n pointer parameters. Change the value of these n formal parameters in this function;
③ Call this function in the calling function, use these n pointer variables as actual parameters when calling, and pass their values, that is, the addresses of related variables to the Formal parameters of the function;
④ During the execution of the function, change the values ​​of the n variables pointed to by the formal parameter pointer variables;
⑤ These variables whose values ​​have been changed can be used in the calling function.
Note: Do not attempt to change the value of the pointer actual parameter by changing the value of the pointer formal parameter.
Note: The function call can (and only can) get a return value (that is, the function value), and use a pointer variable as a parameter to get multiple changed values. It is difficult to do this without pointer variables. Be good at using the pointer method.

2.4, the pointer of the array element

A variable has an address, an array contains several elements, and each array element occupies a storage unit in memory, and they all have corresponding addresses. Since pointer variables can point to variables, of course they can also point to array elements (put the address of an element into a pointer variable). The pointer of the so-called array element is the address of the array element.
You can use a pointer variable to point to an array element. For example:
int a[10] = {0,1,2,3,4,5,6,7,8,9}; // define a as an array int *p containing 10 integer data
; // define p is a pointer variable pointing to an integer variable
p = &a[0]; // Assign the address of the a[0] element to the pointer variable p
printf("%d\n",p[3]); // use the pointer Access the array elements and print out the array of a[3] elements.
The above is to make the pointer variable p point to the 0th element of the a array.
You can use the subscript method (such as a[3]) or the pointer elements . That is, the desired element is found through a pointer to an element of the array. Using the pointer method can make the target program of high quality (occupies less memory and runs faster).
In the C language, the array name (excluding the formal parameter group name) represents the address of the first element in the array (that is, the element whose serial number is 0). Therefore, the following two statements are equivalent:
p = &a[0]; // The value of p is the address of a[0]
p = a; // The value of p is the address of the first element of array a (that is, a[0]) Address
Note: The array name in the program does not represent the entire array, but only the address of the first element of the array. The effect of the above p = a; isAssign the address of the first element of the array a to the pointer variable p instead of assigning the values ​​of each element of the array a to p.
It can be initialized when defining a pointer variable, such as:
int *p = &a[0];
It is equivalent to the following two lines:
int *p ;
p = &a[0]; // should not be written as *p = &a[ 0];


Of course, it can also be written as int *p = a when defining ;
its function is to assign the address of the first element of the a array (ie a[0]) to the pointer variable p (instead of assigning to *p).

3. Summary

Pointers are addresses .
The required variable unit can be found through the address, so to speak, the address points to the variable unit.
Therefore, the address is visually called a pointer.

Guess you like

Origin blog.csdn.net/weixin_44759598/article/details/128733359