Lecture 7: Pointers and Structures (1) (Reading this article is enough for the knowledge points)

Preface: After a week of accumulation, I bring you the most essential parts of pointers and structures (plus some personal understanding), hoping to help everyone.

Table of contents:

1 What is a pointer? ——>The pointer is the address

2 What is the use? ——>Storage the address of the variable type, any type of address can be stored in the pointer

3 Use of first-order pointers

4 Use of second-order pointers

5 pointer array, array pointer

6 pointer function, function pointer

7 Knowledge of structures

8 pointer structure

9 qsort function to sort array types (sorting of various array types)

10 The underlying principle of the qsort function (explained by bubble sort)

3 Use of first-order pointers

The following is the wrong way to write it.

Problem: The pointer can only change the address but not the content of the current location.

Correct way to write it (forgot to add & to the a variable here)

The content can only be changed through variables.

Print array via pointer

4 Use of second-order pointers

Error case:

This way of writing means that the address pointed by the pointer is 0, not the address pointing to a. Remember! ! !

There is also an error in the following use of second-order pointers, because you are assigning the address pointed by p to the address pointed by the second-order pointer, which is still the address pointed by p.

First-order pointers print the contents of the structure array:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct Stu
{
	int age;
	char* name;
};
int main()
{
	//数组的元素类型是结构体
	//这里建立数组结构体
	struct Stu arr[3] = { {.name = "zhangsan",.age = 18}, {19,"lisi"}, {20,"wangwu"}};
	struct Stu* p = arr;
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%s\n",arr[i].age,arr[i].name);//这里是打印结构体的格式
		printf("%d,%s\n", p->age,p->name);//指针来打印结构体格式
		p++;
	}
}

The second-level pointer prints the structure array (it’s just a shell, no big deal)

The *pp here is p, so it will be easier for everyone to understand

But please do not write pp++ below the loop. This is the address accessed by pp + 1, and the address content of the p pointer is unknown, and the compiler will compile errors.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct Stu
{
	int age;
	char* name;
};
int main()
{
	//数组的元素类型是结构体
	//这里建立数组结构体
	struct Stu arr[3] = { {.name = "zhangsan",.age = 18}, {19,"lisi"}, {20,"wangwu"}};
	struct Stu* p = arr;
	struct Stu** pp = &p;
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%s\n",arr[i].age,arr[i].name);
		printf("%d,%s\n", (*pp)->age,(*pp)->name);
		p++;
	}
}

5 pointer array, array pointer

1 A pointer array is an array, and the array stores pointer variables.

Format: (type) * array name []={ }

2 An array pointer is a pointer, a pointer variable, and the pointer points to the address of the array.

Format: (type) (* array name) []={ }

Here it depends on the priority of symbol combination, because the priority of combining array name with [] is greater than *array name, so we need to enclose *array name in parentheses, so as to represent a pointer array

(These two things must be clarified and not confused)

Let’s take a look at the pointer array first!

int main()
{
	int* arr[5] = { 1,2,3,4,5 };
	int i = 0;
	for (; i < 5; i++)
	{
		printf("%d ", arr[i]);//这个arr[i]的意思就是*(arr+i)
	}
	return 0;
}

It’s okay to write it this way (are you surprised?)

Explain it here:

The array arr is originally an address, which is the address of the first element. It can be understood as a pointer, pointing to a constant of type int*, and then the pointer of type int* points to the address of the constant 1, that is to say, *(arr+i) is the content pointed to by int*

int main()
{
	int* arr[5] = { 1,2,3,4,5 };
	int i = 0;
	for (; i < 5; i++)
	{
		printf("%d ", i[arr]);//这个arr[i]的意思就是*(arr+i)
	}
	return 0;
}

Let’s take a look at the array pointer

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct Stu
{
	int age;
	char* name;
};
int main()
{
	//数组的元素类型是结构体
	//这里建立结构体数组指针
	struct Stu arr[3] = { {.name = "zhangsan",.age = 18},{19,"lisi"} ,{20,"wangwu"}};
	struct Stu(*p)[3] = &arr[0];
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%s\n",(*p)[i].age,(*p)[i].name);
		printf("%d,%s\n", (*p)->age,(*p)->name);
	}
}

Application of array pointer to binary array

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	size_t arr[2][2] = {1,2,4,5};
	size_t(*p)[2] = arr;
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
			printf("%d ", p[i][j]);
        printf("\n");
	}
}

6 pointer function, function pointer

Pointer function, the return type of the function is a pointer type, and the pointer is used to receive

Function pointer, the pointer points to the address of the function (the function name is the address)

pointer function

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int* Add(const void* p1,const void* p2)//指针函数
{
	return *(int*)p1 - *(int*)p2;
}
int main()
{
	int a = 0;
	int b = 1;
	printf("%d", Add(&a, &b));
}

Function pointers (let’s make a calculator, transfer table)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h> 
typedef int (*ap)(int, int);//简单的定义函数指针类型名字为ap
int Mul(int x, int y)
{
	return x * y;
}
int Add(int x, int y)
{
	return x + y;
}
int Div(int x, int y)
{
	return x / y;
}
int Sub(int x, int y)
{
	return x - y;
}
int main()
{
	int input = 0;
	do
	{
		int a = 0;
		int b = 0;
		printf("请输入a和b的值:");
		scanf("%d%d", &a, &b);
		printf("*****************************\n");
		printf("******1:乘法	2:加法*******\n");
		printf("******3:除法    4:减法*******\n");
		printf("******0:退出计算器    *******\n");
		printf("*****************************\n");
		printf("请输入你要进行的计算:\n");
		scanf("%d", &input);
		int (*arr[5])(int a,int b) = {NULL,Mul,Add,Div,Sub};
		printf("%d\n", (*arr[input])(a,b));
	} while (input);
	return 0;
}

Callback function: calling a function indirectly using a function

int Mul(int x, int y)
{
	return x * y;
}
int Add(int x, int y)
{
	return x + y;
}
int Div(int x, int y)
{
	return x / y;
}
int Sub(int x, int y)
{
	return x - y;
}
void Calc(int (*pt)(int, int))
{
	int a = 0;
	int b = 0;
	printf("请输入a和b的值:");
	scanf("%d%d", &a, &b);
	printf("计算的答案:");
	int sum = pt(a, b);
	printf("%d\n", sum);
}
int main()
{
	int input = 0;
	int a = 0;
	int b = 0;
	do
	{
		printf("*****************************\n");
		printf("******1:乘法	2:加法*******\n");
		printf("******3:除法    4:减法*******\n");
		printf("******0:退出计算器    *******\n");
		printf("*****************************\n");
		printf("请输入你要进行的计算:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Calc(Mul);
			break;
		case 2:
			Calc(Add);
			break;
		case 3:
			Calc(Div);
			break;
		case 4:
			Calc(Sub);
			break;
		case 0:
			printf("退出计算器");
			break;
		}
	} while (input);
	return 0;
}

7 Structure knowledge points

7-1 Anonymous structure

error code:

struct//没有标签的结构体,叫做匿名结构体,只能用一次
{
	int age;
	char* name;
}s;
int main()
{
	s = { 18,"zhangsan" };

	return 0;
}

General structure expression:

struct Stu
{
	int age;
	char* name;
};
int main()
{
	struct Stu s = { 18,"zhangsan" };//结构体变量的创建

	return 0;
}

Let's simply use a structure type to write a student management system:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h> 
typedef struct Stu std;
struct Stu
{
	int id;
	int age;
	char* name;
};
int main()
{
	struct Stu arr[3] = { {.id = 123456,.age = 18,.name = "zhangsan"},{123457,19,"lisi"},{123458,20,"wangwu"} };
	
	std a = { .id = 123456,.age = 18,.name = "zhangsan" };
	std b = { 123457,19,"lisi" };
	std c = { 123458,20,"wangwu" };
	std* arr1[3] = { &a,&b,&c };
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%d,%s\n",*arr1[i]);
		printf("%d\n",arr1[i]->id);
	}
}

9 qsort function to sort array types (sorting of various array types)

typedef struct Stu std;
struct Stu
{
	int id;
	int age;
	char name[20];
};
//按照学号排序,升序排列
int Cmp(void* p1, void* p2)
{
	return ((std*)p1)->id - ((std*)p2)->id;
}
#include<stdlib.h>
int main()
{
	struct Stu arr[3] = { {.id = 123456,.age = 18,.name = "zhangsan"},{123457,19,"lisi"},{123458,20,"wangwu"} };
	int num = sizeof(arr) / sizeof(arr[0]);
	int size = sizeof(arr[0]);
	qsort(arr, num, size, Cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%d,%s\n", arr[i].id,arr[i].age,arr[i].name);
	}
	return 0;
}

Sort by first letter of name

typedef struct Stu std;
struct Stu
{
	int id;
	int age;
	char name[20];
};
//按照字母首元素排序
int Cmp(void* p1, void* p2)
{
	return strcmp(((std*)p1)->name,((std*)p2)->name);
}
#include<stdlib.h>
int main()
{
	struct Stu arr[3] = { {.id = 123456,.age = 18,.name = "zhangsan"},{123457,19,"lisi"},{123458,20,"wangwu"} };
	int num = sizeof(arr) / sizeof(arr[0]);
	int size = sizeof(arr[0]);
	qsort(arr, num, size, Cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%d,%d,%s\n", arr[i].id,arr[i].age,arr[i].name);
	}
	return 0;
}

The underlying principle is to compare the value of the initial letter ASCll, whichever is larger will be ranked later.

10 The underlying principle of the qsort function (explained by bubble sort)

10-1 Compare integers:

模拟实现qsort函数排序
int cmp(void* p1,void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}
void Swap(void *p1,void*p2 ,int width)
{
	int i = 0;
	for (; i < width; i++)
	{
		char tmp = 0;
		 tmp = *((char*)p1 + i) ;
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}

}
Bubble_sort(void* base, int num,int width,int (*cmp)(void*,void*))
{
	int i = 0;
	int j = 0;
	for (; i < num-1; i++)
	{
		for (j = 0; j <num-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);
			}
		}
	}
}

int main()
{
	int arr[10] = { 1,4,5,3,2,9,7,8,6,0 };
	int num = sizeof(arr) / sizeof(arr[0]);
	Bubble_sort(arr, num, sizeof(arr[0]), cmp);
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

10-2 Compare structure types:

typedef struct Stu std;
struct Stu
{
	int id;
	int age;
	char name[20];
};
//按照字母首元素排序
void Swap(void* p1, void* p2, int size)
{
	int i = 0;
	for (; i < size; i++)
	{
		char tmp = *((char*)p1 + i);
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}
int Cmp(void* p1, void* p2)
{
	return strcmp(((std*)p1)->name, ((std*)p2)->name);
}
void Bubble_name(void* base, int num, int size, int (*Com_name)(void*, void*))
{
	int i = 0;
	int j = 0;
	for (; i < 3; i++)
	{
		for (int j = 0; j < num - 1 - i; j++)
		{
			if (Com_name((char*) base + size*j, (char*)base + size * (j+1)) > 0)
			{
				Swap((char*)base + size * j, (char*)base + size * (j + 1),size);
			}

		}
	}
}

Guess you like

Origin blog.csdn.net/2301_79811170/article/details/134383830