Advanced C language pointer

Keywords: C

catalogue

Character pointer

Pointer array

Array pointer

Function pointer

Function pointer array

Pointer to array of function pointers

Callback function

Character pointer

Character pointer: char*

int main()
{
	char ch = 'w';
	char * pc = &ch;//pc is a variable that points to a character

	const char* p = "hello bit";//"hello bit" is a constant string - stored in the constant area of memory
	//The above expression is used to assign the address of the first character h of the constant string "hello bit" to p
	*p = 'w'; // "hello bit" is placed in a constant string and cannot be modified
	printf("%c\n", *p);
	printf("%s\n", p);

	

	return 0;
}

Note that the string above places the address of the first element of the string in the character pointer.

Here's an interview question:

int main()
{
	char str1[] = "hello bit.";
	char str2[] = "hello bit.";
	const char* str3 = "hello bit.";
	const 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:

str1 [] and str2 [] are different arrays. The array name represents the address of the first element. Their addresses are different, so the first print is the content in else. str3 and str4 store the address of the first element of the constant string, so they are the same.

Pointer array

I talked about pointer arrays in the early stage of pointers. We can simply review them.

Pointer array is an array, which is an array for storing pointers.

int main()
{
	//char* arr[5];//arr is an array of character pointers
	//int* arr2[4];//arr2 is an array of integer pointers

	int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	              //int* int* int* int*
	int* arr2[4] = {&a, &b, &c, &d};//arr2 is an array of integer pointers
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("%d ", *(arr2[i]));
	}

Array pointer

An array pointer is a pointer, which is a pointer to an array.

#include <stdio.h>
int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,0};
    int (*p)[10] = &arr;//Assign the address of array arr to array pointer variable p
    return 0; 
}

Use of array pointers:

void print1(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
void print2(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(arr + i));
	}
}

void print3(int (*parr)[10], int sz)//This is a false demonstration
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", parr[i]);//parr[i] == *(parr+i)
	}
}

void print4(int (*parr)[10], int sz)
{
	//*(parr + 0);//parr[0]
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		//printf("%d ", parr[0][i]);
		//printf("%d ", (*(parr + 0))[i]);
		printf("%d ", (*parr)[i]);//(* parr) is equivalent to the array name of the array pointed to by parr
	}
}

int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int sz = sizeof(arr) / sizeof(arr[0]);

	print4(&arr, sz);

	//print3(&arr, sz);
	//print2(arr, sz);
	//print1(arr, sz);// Print the contents of the ARR array

	return 0;
}

print1() and print2() receive parameters through arrays and pointers. We already know this, but in print3(), we use array pointers to receive parameters. parr[i] stores the address and cannot find the contents. In print4, we first * parr, which is equivalent to finding the array name of the array, Then access the elements in the array through [].

Two dimensional array parameter transfer:

void print1(int arr[3][5], int r, int c)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
//Array pointer
void print2( int(*p)[5], int r, int c)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			printf("%d ", *(*(p + i) + j));
			printf("%d ", p[i][j]);
			printf("%d ", (*(p + i))[j]);
		}
		printf("\n");
	}
}
//
int main()
{
	int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6,3,4,5,6,7 };
	//Two dimensional array parameter transfer
	//print1(arr, 3, 5);
	print2(arr, 3, 5);//arr is the array name, and the array name is the address of the first element
	return 0;
}

print1() receives parameters through a two-dimensional array, and print2() receives parameters through array pointers.

Function pointer

Function pointer: pointer to a function.

The meaning of function name and & function name is the same, both of which are the address of the function.

int Add(int x, int y)
{
	return x + y;
}

int main()
{
	//printf("%p\n", &Add);
	//printf("%p\n", Add);//0x0012ff40 -  int(*)(int,int)
	//int (*pf)(int , int) = &Add;// PF is the address used to store the function - PF is the function pointer variable

	int (*pf)(int, int) = Add;
	int ret = Add(2, 3);
	printf("%d\n", ret);//5

	//ret = (*pf)(4, 5);//9 * put it here, which is equivalent to furnishings
	ret = pf(4, 5); //9 same as above
	printf("%d\n", ret);

	return 0;
}

The meaning of PF and * pf here is the same. In front of * is a decoration. Because pf is equivalent to Add, it is OK not to Add *.

Here are two examples:

1.

int main()
{
	//The code is a function call
	//Resolution:
	// 1. Cast 0 as the address of a function of type void (*) () in the code.
	// 2. Dereferencing the 0 address is to go to the function at the 0 address. The called function has no parameters and the return type is void
	// < C traps and defects >
	//
	(*( void (*)() ) 0)();

	return 0;
}

 2.

typedef void(* pfun_t)(int) ;
//typedef int int32;
int main()
{
	//This code is a function declaration
	//Declared function name signal
	//The signal function has two parameters. The first is of type int, and the second is of type void(*)(int)
	//The return type of the signal function is still the function pointer type of void(*)(int)
	//
	void (* signal(int, void(*)(int) ) )(int);

	//simplify
	pfun_t signal2(int, pfun_t); //Aliasing with typedef

	//void (*)(int) signal(int, void(*)(int));// Wrong writing

	return 0;
}

Function pointer array

Function pointer array: function pointers are stored in the array.

int Add(int x, int y)//int (*)(int, int)
{
	return x + y;
}

int Sub(int x, int y)//int (*)(int, int)
{
	return x - y;
}

int Mul(int x, int y)//int (*)(int, int)
{
	return x * y;
}

int Div(int x, int y)//int (*)(int, int)
{
	return x / y;
}

int main()
{
	//int* arr[10];// Array of integer pointers
	//Function pointer array - an array of function pointers

	//int (*pf1)(int, int) = Add;
	//int (*pf2)(int, int) = Sub;
	//int (*pf3)(int, int) = Mul;
	//int (*pf4)(int, int) = Div;

	//pfArr is an array of function pointers
	int (* pfArr[4])(int, int) = {Add, Sub, Mul, Div};

	return 0;
}

Use of function pointer array:

Write a simple calculator

void menu()
{
	printf("**********************************\n");
	printf("******* 1.add     2. sub    ******\n");
	printf("******* 3.mul     4. div    ******\n");
	printf("******* 0.exit              ******\n");
	printf("**********************************\n");
	//x&y x|y x>>y x<<y x^y
}
int Add(int x, int y)//int (*)(int, int)
{
	return x + y;
}

int Sub(int x, int y)//int (*)(int, int)
{
	return x - y;
}

int Mul(int x, int y)//int (*)(int, int)
{
	return x * y;
}

int Div(int x, int y)//int (*)(int, int)
{
	return x / y;
}

int main()
{
	int input = 0;
	do
	{
		int x = 0;
		int y = 0;
		int ret = 0;
		menu();
		printf("Please select:>");//1
		scanf("%d", &input);

		//Transfer table - C and pointers
		int (*pfArr[5])(int, int) = {0, Add, Sub, Mul, Div};
		                            //0   1   2    3    4
		if (input == 0)
		{
			printf("Exit calculator\n");
		}
		else if(input>=1 && input<=4)
		{
			printf("Please enter 2 operands:>");
			scanf("%d %d", &x, &y);
			ret = pfArr[input](x, y);
			printf("%d\n", ret);
		}
		else
		{
			printf("Selection error\n");
		}
	} while (input);
	return 0;
}

Method 2:

void menu()
{
	printf("**********************************\n");
	printf("******* 1.add     2. sub    ******\n");
	printf("******* 3.mul     4. div    ******\n");
	printf("******* 0.exit              ******\n");
	printf("**********************************\n");
	//x&y x|y x>>y x<<y x^y
}
int Add(int x, int y)//int (*)(int, int)
{
	return x + y;
}

int Sub(int x, int y)//int (*)(int, int)
{
	return x - y;
}

int Mul(int x, int y)//int (*)(int, int)
{
	return x * y;
}

int Div(int x, int y)//int (*)(int, int)
{
	return x / y;
}

void Calc(int(*pf)(int, int))
{
	int x = 0;
	int y = 0;
	int ret = 0;

	printf("Please enter 2 operands:>");
	scanf("%d %d", &x, &y);
	ret = pf(x, y); //Callback function -- must be implemented with a function pointer
	printf("ret = %d\n", ret);
}

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("Exit calculator\n");
			break;
		default:
			printf("Selection error\n");
			break;
		}
	} while (input);
	return 0;
}

Method 2 uses the callback function.

Pointer to array of function pointers

The pointer to the array of function pointers is a pointer. The pointer points to an array, and the elements of the array are function pointers.

Callback function

A callback function is a function called through a function pointer. If you pass the pointer (address) of a function as a parameter to another function, when the pointer is used to call the function it points to, we say it is a callback function. The callback function is not called directly by the implementer of the function, but by another party when a specific event or condition occurs, which is used to respond to the event or condition.

First, let's introduce the qsort() function

void qsort(void* base, 
           size_t num, / / number of elements to be sorted
           size_t width, / / the size of an element, in bytes
           int(* cmp)(const void* e1, const void* e2) //cmp refers to the function used to compare two elements during sorting);

#include <stdlib.h>
#include <string.h>
int cmp_int(const void*e1,const void*e2)
{
	return *(int*)e1 - *(int*)e2;
}

void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}

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);
	print_arr(arr, sz);
}

struct Stu
{
	char name[20];
	int age;
};

int cmp_by_name(const void*e1,const void*e2)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

int cmp_by_age(const void*e1, const void*e2)
{
	return ((struct Stu*)e1)->name - ((struct Stu*)e2)->name;
}

void test2()
{
	struct Stu s[3] = { { "Zhang San", 15 }, { "Li Si", 30 }, { "Wang Wu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	//Sort by name
	//qsort(s, sz, sizeof(s[0]), cmp_by_name);

	//Sort by age
	qsort(s, sz, sizeof(s[0]), cmp_by_age);
}

void Swap(char* buf1, char* buf2,int width)
{
	int i = 0;
	for (i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf1 = tmp;
		buf1++;
		buf2++;

	}
}


//Use callback function to implement a general bubble sorting function
void Bubblesort(void*base,int num,size_t width,int (*cmp)(const void*e1,const void*e2))
{
	int i = 0;
	//Number of trips
	for (i = 0; i < num - 1; i++)
	{
		//Logarithm of comparison
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			if (cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)
			{
				//exchange
				Swap((char*)base + j*width, (char*)base + (j + 1)*width,width);
			}
		}
	}
}
//Test custom BubbleSort
void test3()
{
	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);
	print_arr(arr, sz);
}

void test4()
{
	struct Stu s[3] = { { "Zhang San", 15 }, { "Li Si", 30 }, { "Wang Wu", 10 } };
	int sz = sizeof(s) / sizeof(s[0]);
	//Sort by name
	Bubblesort(s, sz, sizeof(s[0]), cmp_by_name);

	//Sort by age
	//Bubblesort(s, sz, sizeof(s[0]), cmp_by_age);
}

int main()
{
	//Test sort shaping array
	//test1();
	//Test sort struct array
	//test2();
	//Test custom Bubblesort
	//test3();
	//Test the custom Bubblesort sort structure
	test4();
	return 0;
}	

Posted by jasonc310771 on Thu, 04 Nov 2021 18:59:47 -0700