当前位置:网站首页>Advanced level of C language (high level) pointer

Advanced level of C language (high level) pointer

2022-07-07 07:17:00 ℳ white ℳ night ℳ

1. Character pointer

Among the pointer types, we know that one pointer type is character pointer char*
In general use :

int main()
{
    
    char ch = 'w';
    char *pc = &ch;
    *pc = 'w';
    return 0; 
}

Another way to use it is as follows :

int main()
{
    
	const char* pstr = "hello baiye.";// Here is to put a string into pstr Is it in the pointer variable ?
	printf("%s\n", pstr);
	return 0;
}

Code const char* pstr = “hello baiye.”;
It's especially easy for us to think it's a string hello bit Put it in the character pointer pstr In the , however / The essence is to put the string hello baiye. The address of the first character is put in pstr in .
The above code means that the first character of a constant string h The address of is stored in the pointer variable pstr in .

2. Pointer array

We introduced , Not much here .

int* arr1[10]; // An array of integer pointers 
char *arr2[4]; // An array of first-order character pointers 
char **arr3[5];// An array of secondary character pointers 

3. Array pointer

3.1 Definition of array pointer

Array pointers are pointers ? Or arrays ?
The answer is : The pointer .
We are already familiar with :
Shaping the pointer : int * pint; A pointer that can point to shaped data .
Floating point pointer : float * pf; A pointer that can point to floating-point data .
The array pointer should be : A pointer to an array .
Which of the following code is an array pointer ?

int *p1[10];
int (*p2)[10];
//p1, p2 What are the differences ?

P1: It's an array of pointers .
P2:
// explain :p The first and * combination , explain p Is a pointer variable , Then point to a size of 10 An array of integers . therefore p It's a pointer , Point to an array , It's called array pointer .
// Pay attention here :[ ] Priority is higher than * The no. , So we have to add () To guarantee p The first and * combination .

3.2 & Array name VS Array name

Let's look at a piece of code :

#include <stdio.h>
int main()
{
    
    int arr[10] = {
    0};
    printf("%p\n", arr);
    printf("%p\n", &arr);
    return 0; 
}

arr and &arr What's the difference ?
We know arr It's an array name , The array name indicates the address of the first element of the array .
that &arr What is the array name ?
Let's run it first and see the result :
 Insert picture description here
Visible array name and & The address printed by the array name is the same .
Are the two the same ?
Let's take another look at the code :

#include <stdio.h>
int main()
{
    
	int arr[10] = {
     0 };
	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);
	printf("arr+1 = %p\n", arr + 1);
	printf("&arr+1= %p\n", &arr + 1);
	return 0;
}

Running results :
 Insert picture description here
According to the above code, we find that , Actually &arr and arr, Although the values are the same , But the meaning should be different .
actually : &arr Represents the address of the array , Instead of the address of the first element of the array .( Feel it carefully )
In this case &arr The type is : int(*)[10] , Is an array pointer type
Address of array +1, Skip the size of the entire array , therefore &arr+1 be relative to &arr The difference is 40.

3.3 The use of array pointers

How do you use array pointers ?
Since the array pointer points to an array , The array pointer should store the address of the array .
Look at the code :

#include <stdio.h>
int main()
{
    
	int arr[10] = {
     1,2,3,4,5,6,7,8,9,0 };
	int(*p)[10] = &arr;// Put the array arr To an array pointer variable p
	// But we seldom write code like this 
	return 0;
}

The use of an array pointer :

#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col) 
{
    
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
    
		for (j = 0; j < col; j++)
		{
    
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
void print_arr2(int(*arr)[5], int row, int col) 
{
    
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
    
		for (j = 0; j < col; j++)
		{
    
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
    
	int arr[3][5] = {
     1,2,3,4,5,6,7,8,9,10 };
	print_arr1(arr, 3, 5);
	// Array name arr, Represents the address of the first element 
	// But the first element of a two-dimensional array is the first row of a two-dimensional array 
	// So the message here is arr, It's actually equivalent to the address on the first line , Is the address of a one-dimensional array 
	// You can use an array pointer to receive 
	print_arr2(arr, 3, 5);
	return 0;
}

Let's take a look at the run results :
 Insert picture description here
that , What does this code mean ?

int (*parr3[10])[5];

First parr3 and [10] combination , This shows that it is an array , At this time, the array is still missing a type , So the rest int(*)[5] It's the type , In general parr3 Is an array that holds array pointers .

4. Array parameters 、 Pointer parameter

When writing code, it is inevitable to 【 Array 】 perhaps 【 The pointer 】 Pass to function , How to design the parameters of the function ?

4.1 One dimensional array parameters

#include <stdio.h>
void test(int arr[])//ok?
{
    }
void test(int arr[10])//ok?
{
    }
void test(int* arr)//ok?
{
    }
void test2(int* arr[20])//ok?
{
    }
void test2(int** arr)//ok?
{
    }
int main()
{
    
	int arr[10] = {
     0 };
	int* arr2[20] = {
     0 };
	test(arr);
	test2(arr2);
}

These are all right .
The first is how to write an array , the second [] The numbers inside are optional .
The third is the address , As I said before, the array name is the address of the first element , It's also a type , So you can .
The fourth parameter is also the same as the argument .
The fifth one can be accepted with a secondary pointer , Because the argument is a pointer array , The array name is the address of the first element , And elements are pointers , We also know that the secondary pointer stores the address of the primary pointer , So they are a type .

4.2 Two dimensional array parameters

void test(int arr[3][5])//ok?
{
    }
void test(int arr[][])//ok?
{
    }
void test(int arr[][5])//ok?
{
    }
// summary : Two dimensional array parameters , Function parameter design can only omit the first [] The number of .
// Because for a two-dimensional array , I don't know how many lines there are , But you have to know how many elements in a row .
// So it's easy to calculate .
void test(int* arr)//ok?
{
    }
void test(int* arr[5])//ok?
{
    }
void test(int(*arr)[5])//ok?
{
    }
void test(int** arr)//ok?
{
    }
int main()
{
    
	int arr[3][5] = {
     0 };
	test(arr);
}

The first one can , Because what passed is a two-dimensional array , Accept with a two-dimensional array , So you can .
The second one doesn't work , Because two-dimensional arrays can omit rows , You can't omit Columns .
The third one can .
The fourth one is not good , because arr Is the address of the first element of a two-dimensional array , Also represents the first row of the array , That is, a one-dimensional array , So you can't use an integer pointer to receive .
The fifth one is not good , Because this is an array of pointers , Not a type .
The sixth one can , Because it uses an array pointer to receive a one-dimensional array .
Seventh, no , The address of a one-dimensional array cannot be put into a secondary pointer .

4.3 First level pointer parameter transfer

#include <stdio.h>
void print(int* p, int sz) 
{
    
	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
		printf("%d\n", *(p + i));
	}
}
int main()
{
    
	int arr[10] = {
     1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	// First level pointer p, Pass to function 
	print(p, sz);
	return 0;
}

Running results :
 Insert picture description here

4.4 The secondary pointer transmits parameters

#include <stdio.h>
void test(int** ptr) {
    
 printf("num = %d\n", **ptr); 
}
int main()
{
    
 int n = 10;
 int*p = &n;
 int **pp = &p;
 test(pp);
 test(&p);
 return 0; }

The result of the operation is :
 Insert picture description here

5. A function pointer

that , Functions must also have addresses , There is also a corresponding pointer to receive the address of the function .
First look at a piece of code :

#include <stdio.h>
void test()
{
    
	printf("hehe\n");
}
int main()
{
    
	printf("%p\n", test);
	printf("%p\n", &test);
	return 0;
}

Code run results :
 Insert picture description here
The output is two addresses , These two addresses are test Address of function .
That means the function name is the address of the function .
The address of our function should be saved , How to keep ?
Let's look at the code :

void test()
{
    
	printf("hehe\n");
}
// below pfun1 and pfun2 Which has the ability to store test Address of function ?
void (*pfun1)();
void* pfun2();

First , Can give the storage address , Just ask pfun1 perhaps pfun2 Is a pointer , Which is the pointer ?
The answer is :
pfun1 It can store .pfun1 The first and * combination , explain pfun1 Is a pointer , The pointer points to a function , The function pointed to has no parameters
Count , The return value type is void.

6. Function pointer array

An array is a storage space for the same type of data , So we've learned about pointer arrays ,
such as :

int *arr[10];
// Each element of the array is int*

Then save the address of the function in an array , This array is called the function pointer array , How to define the array of function pointers ?

int (*parr1[10])();
int *parr2[10]();
int (*)() parr3[10];

The answer is :parr1
parr1 The first and [] combination , explain parr1 It's an array , What is the content of the array ?
yes int (*)() Function pointer of type .
As for the use of function pointers :
Write a calculator

#include <stdio.h>
int add(int a, int b) {
    
	return a + b;
}
int sub(int a, int b) {
    
	return a - b;
}
int mul(int a, int b) {
    
	return a * b;
}
int div(int a, int b) {
    
	return a / b;
}
int main()
{
    
	int x, y;
	int input = 1;
	int ret = 0;
	int(*p[5])(int x, int y) = {
     0, add, sub, mul, div }; // Transfer table 
	while (input)
	{
    
		printf("*************************\n");
		printf(" 1:add2:sub \n");
		printf(" 3:mul4:div \n");
		printf("*************************\n");
		printf(" Please select :");
		scanf("%d", &input);
		if ((input <= 4 && input >= 1))
		{
    
			printf(" Enter the operands :");
			scanf("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else
			printf(" Incorrect input \n");
		printf("ret = %d\n", ret);
	}
	return 0;
}

Here we see , After selecting the algorithm , It is equivalent to selecting the function pointer in the array , Directly to the above operation function .
This is more convenient .

7. A pointer to an array of function pointers

The pointer to the array of function pointers is a pointer ,
The pointer points to a Array , The elements of the array are function pointers ;
How to define ?

#include <stdio.h>
void test(const char* str) 
{
    
	printf("%s\n", str);
}
int main()
{
    
	// A function pointer pfun
	void (*pfun)(const char*) = test;
	// An array of function pointers pfunArr
	void (*pfunArr[5])(const char* str);
	pfunArr[0] = test;
	// Pointer to function array pfunArr The pointer to ppfunArr
	void (*(*ppfunArr)[5])(const char*) = &pfunArr;
	return 0;
}

ha-ha , This is the dolls

8. Callback function

A callback function is a function called through a function pointer . If you put a pointer to a function ( Address ) Pass as a parameter to another
function , When this pointer is used to call the function it points to , Let's just say this is a callback function . The callback function is not controlled by this function
The implementer of directly calls , It's called by another party when a particular event or condition occurs , Used to enter the event or condition
Row response .

First demonstrate qsort( Click here to view in detail qsort function ) Use of functions :

#include <stdio.h>
#include <stdlib.h>
//qosrt The user of the function has to implement a comparison function 
int int_cmp(const void* p1, const void* p2) 
{
    
	return (*(int*)p1 - *(int*)p2);
}
int main()
{
    
	int arr[] = {
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	int i = 0;

	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
    
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

The running result of the code :
 Insert picture description here
Here we can use bubble sorting and callback functions to simulate the implementation qsort function .
Below void* There is no specific type of pointer , The function is to receive any type of pointer , It can also be assigned to any type of pointer .

#include <stdio.h>
int int_cmp(const void* p1, const void* p2) 
{
    
	return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size) 
{
    
	int i = 0;
	for (i = 0; i < size; i++)
	{
    
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);// use char The pointer of type has a length of 1 Bytes , Whether we want int Type or ling Types are added byte by byte .
		*((char*)p2 + i) = tmp;
	}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))// Here we use the callback function .
{
    
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
    
		for (j = 0; j < count - i - 1; j++)
		{
    
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
    
				_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
int main()
{
    
	int arr[] = {
     1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	int i = 0;
	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
    
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

The code runs as follows :
 Insert picture description here

Conclusion

Here we are C The pointer of the language is over , Because there was a basic chapter of pointer , Therefore, the number of words in this chapter is relatively small .
Please point out the mistakes and deficiencies , If you think the article is good, please give your family a compliment !!!

原网站

版权声明
本文为[ℳ white ℳ night ℳ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207070330262038.html