C language foundation - 2, pointer

1, Basic concept of pointer

A pointer is a variable type whose value is an address. In 32-bit system, the pointer occupies 4 bytes, and in 64 bit system, the pointer occupies 8 bytes.

When declaring a pointer, the pointer should be initialized and set to NULL when it is no longer used

Wild pointer: uninitialized pointer

Dangling pointer: the memory originally pointed to by the pointer has been released

 1 void test_0() {
 2     int i = 136;
 3     //Define a Int Type pointer ptr_i
 4     //Its value is i Address of
 5     int *ptr_i = &i;
 6     printf("i Your address is:%p\n", &i);//000000000061FDEC
 7     printf("ptr_i The value of is:%p\n", ptr_i);//000000000061FDEC
 8     //Pointer is also a variable type, and it also has its own address
 9     printf("ptr_i Your address is:%p\n", &ptr_i);//000000000061FDE0
10     //In 32-bit system, the pointer occupies 4 bytes, and in 64 bit system, the pointer occupies 8 bytes
11     printf("The size of the pointer is:%d\n", sizeof(ptr_i));//8
12     //The output results of the following are 8 (64 bit system)
13     printf("%d\n", sizeof(int *));//8
14     printf("%d\n", sizeof(char *));//8
15     printf("%d\n", sizeof(long long *));//8
16     printf("%d\n", sizeof(void *));//8
17     //We can assign any other type of pointer to Void Type pointer, For example:
18     void *ptr_v;
19     printf("Before assignment void The address of type pointer is:%p\n", &ptr_v);//000000000061FDD8
20     ptr_v = ptr_i;
21     printf("%p\n", ptr_v);//000000000061FDEC
22     //Of course, it's just assignment, and its own address remains unchanged
23     printf("After assignment void The address of type pointer is:%p\n", &ptr_v);//000000000061FDD8
24 }

To better understand pointers, look at another example of data exchange

1 void swap(int x, int y) {
2     printf("Before exchange x=%d, y=%d\n", x, y);
3     int temp = y;
4     y = x;
5     x = temp;
6     printf("After exchange x=%d, y=%d\n", x, y);
7 }

1 int main() {
2     int c = 2, d = 3;
3     printf("Before exchange c=%d, d=%d\n", c, d);
4     //This exchange has no effect because values are passed into the method
5     swap(c, d);
6     printf("After exchange c=%d, d=%d\n", c, d);
8     return 0;
9 }

The above method can not achieve the purpose of exchange. Although the swap method completes the exchange of x and y values, we pass in the values of c and d in the Main method

So after the exchange, the addresses of c and d in the main method are still the previous values

The code output result is:

1 Before exchange c=2, d=3
2 Before exchange x=2, y=3
3 After exchange x=3, y=2
4 After exchange c=2, d=3

So the correct exchange posture is to use the pointer

 1 //Pointer passing, passing is the address of the variable
 2 //*x express x The value on the address is still the value exchanged internally in this method
 3 void swap1(int *x, int *y) {
 4     printf("The incoming address is: x=%p, y=%p\n", x, y);
 5     printf("Value on address: before exchange x=%d, y=%d\n", *x, *y);
 6     int temp = *y;
 7     *y = *x;
 8     *x = temp;
 9     printf("Value on address: after exchange x=%d, y=%d\n", *x, *y);
10 }
13 int main() {
15     //The correct way is to pass the address
16     c = 20, d = 30;
17     printf("Before exchange c=%d, d=%d\n", c, d);
18     printf("c and d Your address is:&c=%p, &d=%p\n", &c, &d);
19     //Pointer passing, passing the address of a variable
20     swap1(&c, &d);
21     printf("After exchange c=%d, d=%d\n", c, d);
22     return 0;
23 }

The swap1 method is internally exchanged, but when we call it in the Main method, we import the addresses of variables c and d.

Then, in the swap method, the exchange is carried out according to the address value, so the addresses of c and d remain unchanged after operation, but the values on the address are exchanged:

1 Before exchange c=20, d=30
2 c and d Your address is:&c=000000000061FE1C, &d=000000000061FE18
3 The incoming address is: x=000000000061FE1C, y=000000000061FE18
4 Value on address: before exchange x=20, y=30
5 Value on address: after exchange x=30, y=20
6 After exchange c=30, d=20


2, Basic operation of pointer

&Operator, take address

*Dereference, also known as indirect addressing character* p gets the value at the address pointed to by the pointer p

&And * are a pair of reciprocal operations

 1 void test_2() {
 2     //definition int Type variable a,The value is 10
 3     int a=10;
 4     //definition int Type pointer p, Its value is a variable a Address of
 5     int *p = &a;
 6     //*p Represents a pointer p The value on the address pointed to, that is, dereference
 7     int pv = *p;
 8     printf("a=%d\n", a);//10
 9     printf("pv=%d\n", pv);//10
10     //To assign a value to a dereference is to assign a pointer p Memory assignment on the address pointed to
11     *p=100;
12     printf("a=%d\n", a);//100
13 }

Pointer arithmetic operation: for variables, the space occupied by different types is different; However, different types of pointers occupy the same space (4 bytes in 32-bit system and 8 bytes in 64 bit system). Since the occupied space is the same, why divide pointers into various types? Is for the arithmetic operation of the pointer.   The pointer can only perform addition and subtraction operations, including +, -, + +, -, + =-=

1 int i = 100;
2     //definition Int Type pointer ptr, Its value is i Address of
3     int *ptr = &i;
4     printf("%p\n", ptr);//000000000061FDE4
5     //int Type takes up 4 bytes
6     printf("%p\n", ptr+1);//000000000061FDE8
7     printf("%p\n", ptr+2);//000000000061FDEC

s in the above code, ptr is an Int pointer, so ptr+1 will move 4 bytes

1 char c = 100;
2     //definition char Type pointer ptr, Its value is c Address of
3     char *ptr_c = &c;
4     printf("%p\n", ptr_c);//000000000061FDDB
5     //char Type takes up 1 byte
6     printf("%p\n", ptr_c-1);//000000000061FDDA
7     printf("%p\n", ptr_c+1);//000000000061FDDC
8     printf("%p\n", ptr_c+2);//000000000061FDDD

ptr_c is a char pointer, so only one byte is moved at a time

Therefore, we say that the step of pointer movement is related to the type it refers to

Pointers and one-dimensional arrays:

In c language, we usually define an Int array as follows:

int array[] = {11,22,33,44,55};

Note: the array name array can represent the starting address of the array, the address of the first element of the array, and a constant pointer

1    int array[] = {11,22,33,44,55};
2     printf("array=%p\n", array);//000000000061FDD0
3     int *ptr_array = array; //Note that there is no need here = &array, Because the array name is just a pointer
4     printf("ptr_array=%p\n", ptr_array);//000000000061FDD0
6     printf("&array%p\n", &array);//000000000061FDD0, The array name is the starting address of the array
7     printf("&array[0]=%p\n", &array[0]);//000000000061FDD0, It is also the address of the first element

In the above code, the addresses of array, & array, & array [0] are the same

We can use array[2]=100; To change the value of the third element in the array to 100

You can also operate through pointers

1     ptr_array[2] = 50;
2     printf("array[2]= %d\n", array[2]);//50

Or combined with the arithmetic operation of the pointer

1 *(ptr_array+1) = 888;//Indicates that the pointer advances one step, and then assigns the above value to 888
2     printf("%d\n", array[0]);//11
3     printf("%d\n", array[1]);//888
4     printf("%d\n", array[2]);//50

above   * (ptr_array+1)=888; Equivalent to array[1]=888; Equivalent to * (array+1)=888;

 1 //Summary: array+3,  &array[3], ptr_array+3, &ptr_array[3]  They represent the same address
 2     printf("=====%p\n",array+3);
 3     printf("=====%p\n",&array[3]);
 4     printf("=====%p\n",ptr_array+3);
 5     printf("=====%p\n",&ptr_array[3]);
 6     //Similarly, *(array+3),  *&array[3], *(ptr_array+3), *&ptr_array[3]  They represent the same value
 7     printf("=====%d\n",*(array+3));
 8     printf("=====%d\n",array[3]);
 9     printf("=====%d\n",*(ptr_array+3));
10     printf("=====%d\n",ptr_array[3]);


Array pointer and pointer array???

1 int (*ptr)[5]        //Array pointer,
2 int *ptr_array[5]       //Pointer array

For the code int (*ptr)[5], we first define a pointer whose name is ptr,  

                                          Int modifies the contents of the array, indicating that each element of the array is int

                                            So, it's an array pointer to   An array containing five Int types (or the type of this pointer is   An array containing 5 ints). The array has no name here. It is an anonymous array.  


For code int *ptr_array[5],   Since [] has a higher priority than *, PTR should be performed first_ Array and [] are combined to get an array, and then Int * indicates that each element of the array is an Int pointer

1        int (*ptr)[5] = &array; //correct
2 //    int (*ptr_1)[5] = array;//Will report an error, can't put one Int Type pointer is assigned to an array pointer of different types
3 //    int (*ptr_2)[4] = &array;//An error is reported. You cannot change one type to 5 Int The array pointer of is assigned to a type of 4 int Array pointer to

The above code can well prove this problem

Note the difference between array and & array, although the printed addresses are the same,   But array is the address of the first element of the array, and & array is the address of the array

 1     //Define an array
 2     int array[] = {11,22,32,44,51};
 3     //Define a pointer
 4     int *ptr_array = array;
 5     printf("array=%p\n", array);//000000000061FDD0
 6     printf("&array=%p\n", &array);//000000000061FDD0
 8     //The step size is one INT Bytes of type
 9     printf("array+1=%p\n", array+1);//000000000061FDD4
10     //The offset is array[5]Type, the array as a whole as an offset unit
11     printf("&array+1=%p\n", &array+1);//000000000061FDE4

Therefore, in the above code, array+1 is offset by 4 bytes relative to array; And & array+1 offsets the length of an array -- 5 elements * 4 bytes per element = 20 bytes


Traversal of array:

1     for (int i=0; i<5; i++) {
2         printf("%d\n", array[i]);
3     }
5     //A simple application of pointer---Traverses the array as a pointer
6     int* p=NULL;
7     for(p=array; p<array+5; p++){
8         printf("address:%p=====%d\n",p, *p);
9     }

Posted on Thu, 02 Dec 2021 17:20:48 -0500 by Jayson