<> Pointer advanced

<>1. Character pointer

<> Common situations

Among the types of pointers, we know that one type of pointer is character pointer char* ;
General use :
int main() { char ch = 'w'; char *pc = &ch; *pc = 'w'; return 0; }
Another way to use it is as follows :
int main() { char* pstr = "hello bit.";// Here is to put a string into pstr Is it in the pointer variable ? printf("%s\n",
pstr); return 0; }
code char pstr = “hello bit.”; It's especially easy for students to think it's a string hello bit Put character pointer pstr
Inside , however / The essence is to put the string hello bit. 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 the pointer is stored in the pointer variable pstr in

<> Examples

Judge the output result :
#include <stdio.h> int main() { char str1[] = "hello bit."; char str2[] =
"hello bit."; char *str3 = "hello bit."; char *str4 = "hello bit."; if(str1 ==
str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not
same\n"); if(str3 ==str4) printf("str3 and str4 are same\n"); else printf("str3
and str4 are not same\n"); return 0; }
Output results :

here str3 and str4 Refers to the same constant string .
C/C++ The constant string is stored in a separate memory area , When several pointers point to the same string , They actually point to the same block of memory
. However, when initializing different arrays with the same constant string, different memory blocks will be opened up . therefore str1 and str2 Different ,str3 and str4 Different .

<>2. Pointer array

Pointer array is an array of pointers .
int* arr1[10]; // Array of integer pointers char *arr2[4]; // Array of first level character pointers char **arr3[5];// Array of secondary character pointers
<>3. Array pointer

<> Determine which of the following code is an array pointer ?

Array pointers are pointers to array elements
int *p1[10]; int (*p2)[10]; //p1, p2 What are they ? int (*p)[10]; explain :p First and *
combination , explain p Is a pointer variable , Then point to a size of 10 An array of integers . therefore p Is a pointer , Point to an array , Array pointer . Pay attention here :[] Priority over *
No , So you have to add () To guarantee p First and * combination . and int *p1[10] Is an array of pointers .
<>& Array name and Array name

For the following array ,arr and &arr What are the differences ?
int arr[10];
We know arr Is the array name , The array name table shows the address of the first element of the array .
that &arr What is the 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; }
The operation results are as follows :

Visible array name and & The array name and the printed address are the same .
Are the two the same ?
Let's look at another piece of 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; }
The operation results are as follows :

According to the above code, we find that , actually &arr and arr, Although the value is the same , But the meaning should be different .
actually : &arr Represents the address of the array , Not the address of the first element of the array .( Feel it carefully ) Address of array +1, Skip entire array size , therefore
&arr+1 be relative to &arr The difference is 40.

<> Use of array pointers

1. 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 array arr The address of is assigned to the array pointer variable p // But we seldom write code like this return 0; }
2. Print 2D array
#include<stdio.h> void print_arr1(int (*arr)[5], int row, int col) { int i = 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};
// Array name arr, Represents the address of the first element // But the first element of the two-dimensional array is the first row of the two-dimensional array // So what's passed here arr, It's actually equivalent to the address on the first line , Is the address of a one-dimensional array
// You can use array pointers to receive print_arr1(arr, 3, 5); return 0; }
<>4. Array parameter passing and pointer parameter passing

When writing code, it is inevitable to 【 array 】 perhaps 【 Pointer 】 Pass to function , How to design the parameters of the function ?

<> One dimensional array parameter transfer
#include <stdio.h> void test(int arr[])//ok? {} void test(int arr[10])//ok? {}
void test(int *arr)//ok? {} // Top three : The address of the first element of the array is , Can be received in an array , It can also be received with a primary pointer void
test2(int *arr[20])//ok? {} // No problem void test2(int **arr)//ok? {}
// The array name of a one-dimensional array is the address of the first element of the array , The first element here is the first level pointer , There is nothing wrong with the secondary pointer to receive the address of the primary pointer int main() { int arr[10] = {0
}; int *arr2[20] = {0}; test(arr); test2(arr2); }
<> Two dimensional array parameter transfer
void test(int arr[3][5])//ok? {} void test(int arr[][])//ok? no way {} void test(
int arr[][5])//ok? {} // summary : Two dimensional array parameter transfer , The design of function parameters can only omit the first one [] 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 are in a row . // This is convenient for calculation . void test(int *arr)//ok? //no {}
void test(int* arr[5])//ok? //no {} void test(int (*arr)[5])//ok? //no {} void
test(int **arr)//ok? //ok {} int main() { int arr[3][5] = {0}; test(arr);
// The address of the first element of the array name of the two-dimensional array , The address of the first element of a two-dimensional array is the address of the first row of the array // The first row is a one-dimensional array
// If you want to receive in the form of a pointer , Receive address of one-dimensional array , You must use array pointers . }
<>5. Function pointer

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; }
Operation results :

Two addresses are output , Both addresses are test Address of the function , No difference

The address of our function should be saved , How to save ?
Let's look at the code :
void test() { printf("hehe\n"); } // below pfun1 and pfun2 Which has the ability to store test Address of the function ? void (*pfun1
)(); void *pfun2();
pfun1 Can store .pfun1 First and * combination , explain pfun1 It's a pointer , The pointer points to a function , Function pointed to none parameter , The return value type is void.

<>6. Function pointer array

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

<> Definition of function pointer array
int (*parr1[10])(); int *parr2[10](); int (*)() parr3[10]; // Which of the above definitions is a function pointer array ?
parr1 First and [ ] combination , explain parr1 Is an array , What is the content of the array ?
yes int (*)() Function pointer of type .

<> Purpose of function pointer array —— Transfer table
#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:add 2:sub \n" ); printf( " 3:mul
4:div \n" ); printf( "*************************\n" ); printf( " Please select :" ); scanf(
"%d", &input); if ((input <= 4 && input >= 1)) { printf( " Input operand :" ); scanf( "%d
%d", &x, &y); ret = (*p[input])(x, y); } else printf( " Incorrect input \n" ); printf( "ret
= %d\n", ret); } return 0; }
int (* p[5]) (int x,int y) = { 0, add, sub, mul, div }; // Transfer table
significance : array p Every element in is int (*)(int int) type

<>7. Pointer to array of function pointers

<> What is a pointer to an array of function pointers ?

The pointer to the array of function pointers is a Pointer ,
Pointer to a array ,
The elements of the array are Function pointer ;

How to define :
#include<stdio.h> void test() { return; } int main() { // Function pointer void(*pf)() = &
test; // Function pointer array void(*ppf[4])() = { pf, pf, pf, pf }; // Pointer to array of function pointers void(*(*pppf)
[4])() = &ppf; }

<>8. Callback function

<> What makes a callback function ?

A callback function is a function called through a function pointer .

If you put the pointer of the function ( address ) Pass as an argument to another function , When this pointer is used to call the function it points to , Let's say this is a callback function . The callback function is not called directly by the implementer of the function , It is called by another party when a specific event or condition occurs , Used to respond to the event or condition .

<> Application of callback function —— Advanced bubble sort
#include<stdio.h> #include<stdlib.h> #include<string.h> struct stu{ char name[
20]; int age; float score; }; int cmp_int(const void* e1, const void* e2) {
return *(int*)e1 - *(int*)e2; } int cmp_stu_by_name(const void* e1, const void*
e2) { return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name); } int
cmp_stu_by_score(const void* e1, const void* e2) { //return ((struct
stu*)e1)->score - ((struct stu*)e2)->score;
// be careful : Don't use the above method , Here are floating point numbers , For example 0.9-0.8, Because the return type is int type , This causes the return value to 0 if (((struct stu*)e1)->
score> ((struct stu*)e2)->score) { return 1; } else if (((struct stu*)e1)->score
< ((struct stu*)e2)->score) { return -1; } else { return 0; } } void Print_stu(
struct stu *arr, int size) { int i = 0; for (i = 0; i < size; i++) { printf("%s
%d %f\n", arr[i].name, arr[i].age, arr[i].score); } } void Print_int(int* arr,
int size) { int i = 0; for (i = 0; i < size; i++) { printf("%d ", arr[i]); } }
// One byte One byte exchange void swap(char* buf1, char* buf2, int width) { int i = 0; for (i
= 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++;
buf2++; } } // Bubble sorting ( Array start position , Array size , Array element width , Comparison method ) void bubble_sort(void *base, int
size, int width, int(*cmp)(const void* e1, const void* e2)) { int i = 0; for (i
= 0; i < size-1; i++) { int j = 0; for (j = 0; j < size - 1 - i; j++) { if (cmp(
(char*)base + j*width, (char*)base + (j + 1)*width)>0) { swap((char*)base + j*
width, (char*)base + (j + 1)*width, width); } } } } // test int Type data sorting void test1()
{ int arr[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; int size = sizeof(arr) /
sizeof(arr[0]); bubble_sort(arr, size, sizeof(arr[0]), cmp_int); Print_int(arr,
size); } // test structural morphology ——name sort void test2() { struct stu arr[3] = { { "zhangsan", 50
, 70.9f }, { "lisi", 30, 80.34f }, {"wangmazi",70,60.25f} }; int size = sizeof(
arr) / sizeof(arr[0]); bubble_sort(arr, size, sizeof(arr[0]), cmp_stu_by_name);
Print_stu(arr, size); } // test structural morphology ——score sort void test3() { struct stu arr[3] = {
{ "zhangsan", 50, 70.9f }, { "lisi", 30, 80.34f }, { "wangmazi", 70, 60.25f } };
int size = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, size, sizeof(arr[0]),
cmp_stu_by_score); Print_stu(arr, size); } int main() { //test1(); //test2();
test3(); return 0; }

Technology