preface
1. Pointer is a variable used to store address. The address uniquely identifies a piece of memory space.
2. The size of the pointer is fixed 4 / 8 bytes (32-bit operating system / 64 bit operating system).
3. Pointers are typed. The type of pointer determines the step size of ± integer and the permission of operation memory size when pointer dereference.
4. Pointer operation.
Tip: the following is the main content of this article. The following cases can be used for reference
1, Character pointer
Character pointer char in pointer type*
Example:
int main() { char a = 'a'; char* p = &a; return 0; }
int main() { char arr[] = "abcdef"; char* p = arr; printf("%s\n", arr); //Output abcdef printf("%s\n", p); //Output abcdef return 0; } //There is another way to write void test() { //abcdef is a constant char* p = "abcdef"; //p is the address of the first element printf("%c\n", *p); //Output a printf("%c\n", p); //Output abcdef }
Related interview questions
int main() { char arr1 = "abcdef"; char arr2 = "abcdef"; char* p1 = "abcdef"; char* p2 = "abcdef"; if (arr1 == arr2) { printf("arr1 = arr2"); } else { printf("arr1 != arr2"); } if (p1 == p2) { printf("p1 = p2"); } else { printf("p1 != p2"); } return 0; //1. Output arr1 = arr2 //2. Output p1 = p2 //Because char* p1 = "abcdef"; //char* p2 = "abcdef"; //abcdef is a constant, so P1 and P2 point to the same location of the first element }
2, Array pointer
Is the array pointer an array? Or a pointer? The answer is: pointer.
int main() { int* p = NULL; //The shaping pointer points to the shaping pointer, which can store the shaping address char* cp = NULL; //Character pointer pointer to a character Address where characters can be stored int arr[10] = {0}; //Array pointer a pointer to an array that can hold the address of the array //Arr and arr[0] are the first element addresses //&Arr is the address of the array return 0; }
Array pointer:
int main() { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int (*p)[10] = &arr; return 0; }
Exercise of using array pointer:
void print(int (*p)[5], int row, int col) { for( int i = 0; i < row; i++ ) { //printf("%p \n", *(p + i)); // Address of each line for( int j = 0; j < col; j++ ) { printf("%d ", *(*(p + i) + j)); //Each row, each element //printf("%d ", (*(p + i))[j]); // Each row, each element //printf("%d ", p[i][j]); // Each row, each element } printf("\n"); } } int main() { int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6}, {3,4,5,6,7}}; print(arr, 3, 5); return 0; }
3, Pointer array
Pointer array is an array used to store pointers
int main() { int arr[10] = { 0 }; //Shaping array char ch[10] = { 0 }; //Character array int* pArr[10]; //Integer pointer array char* cArr[10]; //Character pointer array return 0; }
Use of pointer array
int main() { int arr1[] = {1, 2, 3, 4, 5}; int arr2[] = {6, 7 ,8 ,9 , 0}; int arr3[] = {12, 23, 34, 45, 56}; //Pointer array int* pArr[] = {arr1, arr2, arr3}; //Gets each element of three arrays for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("%d ", *(pArr[i] + j)); } printf("\n"); } return 0; }
4, Array parameter passing and pointer parameter passing
One dimensional array
void test1(int arr[]){} //ok? ok void test1(int* arr[]){} //ok? ok void test1(int arr[10]){} //ok? ok void test2(int *arr[20]){} //ok? ok void test2(int **arr){} //ok? ok int main() { int arr[10] = {0}; int* arr2[20] = {0}; test1(arr); test2(arr2); return 0; }
Two dimensional array
void test(int *arr){} //ok? err! void test(int *arr[5]){} //ok? err! void test(int (*arr)[5]){} //ok? ok! void test(int **arr){} //ok? err! int main() { int arr[3][5] = {0}; test(arr); return 0; }
Secondary pointer transfer parameter
void test(int** pp) {} int main() { int a = 10; int* p = &a; int** pp = &p; test(pp); return 0; }
5, Function pointer
Pointer to function
&Both the function name and the function name are the address of the function
int Add(int x, int y) { return x + y; } void Print(char* str) { printf("%s ", str); } int main() { int a = 10; int b = 20; int (*p)(int, int) = Add; int ret = (*p)(a, b); printf("%d\n", ret); void (*p2)(char*) = Print; (*p2)("hello world"); return 0; }
6, Function pointer array
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int (*parr[4])(int, int) = {Add, Sub, Mul, Div}; for (int i = 0; i < 4; i++) { int result = parr[i](10, 20); printf("%d\n", result); } return 0; }
practice:
char* my_strcpy(char* dest, const char* src)
Write a function pointer and function pointer array, the array length is 4
#include <stdio.h> char* my_strcpy(char* dest, const char* src) { } int main() { char* (*pf)(char*, const char*) = my_strcpy; char* (*pf[4])(char*, const char*); }
The function pointer array case implements a calculator:
Write a function pointer array first:
#include <stdio.h> void menu() { printf("***************************\n"); printf("*****1. add 2. sub ****\n"); printf("*****3. mul 4. div ****\n"); printf("***** 0. ext ****\n"); printf("***************************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int input = 0; int x = 0; int y = 0; do { menu(); printf("Please select:>"); scanf("%d", &input); switch(input) { case 1: printf("Please enter two operands:>"); scanf("%d%d", &x,&y); printf("%d\n", Add(x, y)); break; case 2: printf("Please enter two operands:>"); scanf("%d%d", &x,&y); printf("%d\n", Sub(x, y)); break; case 3: printf("Please enter two operands:>"); scanf("%d%d", &x,&y); printf("%d\n", Mul(x, y)); break; case 4: printf("Please enter two operands:>"); scanf("%d%d", &x,&y); printf("%d\n", Div(x, y)); break; case 0: printf("sign out\n"); break; default: printf("Input error, please re-enter"); break; } } while(input); return 0; }
After using the function pointer array:
#include <stdio.h> //The menu, add, sub, Mul and div functions are the same as those above, so they are omitted. The main function is changed void menu() { printf("***************************\n"); printf("*****1. add 2. sub ****\n"); printf("*****3. mul 4. div ****\n"); printf("*****5. xor ****\n"); printf("***** 0. ext ****\n"); printf("***************************\n"); } //At this point, if we want to add another bit operation method //There is no need to change a lot of code and it is easier to maintain int Xor(int x, int y) { return x ^ y; } int main() { int input = 0; int x = 0; int y = 0; int (*pf[])(int, int) = {0, Add, Sub, Mul, Div, Xor}; do { menu(); printf("Please select:>"); scanf("%d", &input); if (input >= 1 && input <= 5) { printf("Please enter two operands:>"); scanf("%d%d", &x, &y); int result = pf[input](x, y); printf("%d\n", result); } else if (input == 0) { printf("sign out\n"); } else { printf("Input error,Please re-enter"); } } while(input); return 0; }
7, Pointer function pointer array pointer
int main() { int arr[10] = {0}; int (*p)[10] = &arr; //Pointer array int (*pfArr[4])(int, int); //pfArr is an array of function pointers int (*(*ppfArr)[4])(int, int) = &pfArr;//Pointer to array of function pointers //ppfArr is an array pointer. The array pointed to by the pointer has four elements //The type of each element of the array pointed to is a function pointer //The type of that function pointer is int(*)(int, int) return 0; }
8, Callback function
A callback function is a function called through a function pointer.
Case:
For example, the Switch case implementation in the function pointer array above has a lot of redundant code, which can be optimized by callback function.
#include <stdio.h> void menu() { printf("***************************\n"); printf("*****1. add 2. sub ****\n"); printf("*****3. mul 4. div ****\n"); printf("***** 0. ext ****\n"); printf("***************************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void Calc(int (*fp)(int, int)) { int x = 0; int y = 0; printf("Please enter two operands:>"); scanf("%d%d", &x,&y); printf("%d \n", fp(x, y)); } int main() { int input = 0; do { menu(); printf("Please select:>"); scanf("%d", &input); switch(input) { case 1: Calc(Add); break; case 2: Calc(Sub); break; case 3: Calc(Mul); break; case 4: Calc(Div); break; case 0: printf("sign out\n"); break; default: printf("Input error, please re-enter"); break; } } while(input); return 0; }
Case 2:
//Use of qsort function void qsort(void *base, size_t num, size_t width, int(*cmp)(const void *e1, const void *e2) );
Let's write a simple bubble sort first, so that we can know what to do next
void bubble_sort(int arr[], int sz) { for(int i = 0; i < sz - 1; i++) { for (int j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } int main() { int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int sz = sizeof(arr)/sizeof(arr[0]); bubble_sort(arr, sz); for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
However, we found that bubble sorting can only sort integer arrays. If the array to be sorted is a float type array or structure array or any other type of array, sorting cannot be realized.
The C library function qsort just solves this problem. Let's see how it is used.
#include <stdio.h> #include <stdlib.h> #include <string.h> /*test1,2,3,4 Functions bubble sort with different data types*/ int cmp_int(const void* e1, const void* e2) { //Compare two shaping values return *(int*)e1 - *(int*)e2; } int cmp_float(const void* e1, const void* e2) { //Compare two shaping values return ((int)(*(float*)e1 - *(float*)e2)); } void test1() { int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int sz = sizeof(arr)/sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } void test2() { float arr[] = {9.0, 8.0, 7.0, 6.0, 5.0}; int sz = sizeof(arr)/sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_float); for (int i = 0; i < sz; i++) { printf("%f ", arr[i]); } printf("\n"); } struct Stu { char name[20]; int age; }; int cmp_stu_by_age(const void*e1, const void*e2) { return ((struct Stu*)e1) -> age - ((struct Stu*)e2) -> age; } int cmp_stu_by_name(const void*e1, const void*e2) { //Compare strings using the strcmp function of the string library function return strcmp(((struct Stu*)e1) -> name, ((struct Stu*)e2) -> name); } void test3() { struct Stu stu[3] = { {"Zhang San", 33 }, {"Li Si", 22 }, { "Wang Wu", 11 } }; int sz = sizeof(stu)/sizeof(stu[0]); qsort(stu, sz, sizeof(stu[0]), cmp_stu_by_age); for (int i = 0; i < sz; i++) { printf("%s ", stu[i].name); } } void test4() { struct Stu stu[3] = { {"Zhang San", 33 }, {"Li Si", 22 }, { "Wang Wu", 11 } }; int sz = sizeof(stu)/sizeof(stu[0]); qsort(stu, sz, sizeof(stu[0]), cmp_stu_by_name); for (int i = 0; i < sz; i++) { printf("%d ", stu[i].age); } } int main() { test1(); test2(); test3(); test4(); return 0; }
Write a qsort function
#include <stdio.h> struct Stu { char name[20]; int age; }; void Swap(char* buf1, char* buf2, int width) { for (int i = 0; i < width; i++) { char tmp = *buf1; *buf1 = *buf2; *buf2 = tmp; buf1++; buf2++; } } void my_qsort(void* base, int sz, int width, int (*cmp)(void* e1, void* e2)) { for (int i = 0; i < sz - 1; i++) { for (int j = 0; j < sz - 1 - i; j++) { if (cmp((char*)base + j*width, (char*)base + (j + 1)*width) > 0) { //Swap two elements Swap((char*)base + j*width, (char*)base + (j + 1)*width, width); } } } } int cmp_stu_by_age(const char* el1, const char* el2) { return ((struct Stu*)el1) -> age - ((struct Stu*)el2) -> age; } int main() { struct Stu stu[] = { { "Zhang San", 20 }, { "Li Si", 18 } }; int sz = sizeof(stu) / sizeof(stu[0]); my_qsort(stu, sz, sizeof(stu[0]), cmp_stu_by_age); for (int i = 0; i < sz; i++) { printf("%s\n", stu[i].name); } return 0; }