当前位置:网站首页>C language --- advanced pointer

C language --- advanced pointer

2022-04-23 15:42:00 Tea rainbow

Catalog

One 、 Character pointer

Two 、 Pointer array

3、 ... and 、 Array pointer

1. Definition of array pointer

2.& Array name VS Array name

3. The use of array pointers

Four 、 Array parameters 、 Pointer parameter

1. One dimensional array parameters

2. Two dimensional array parameters

3. First level pointer parameter transfer

4. The secondary pointer transmits parameters

5、 ... and 、 A function pointer

6、 ... and 、 Function pointer array

7、 ... and 、 A pointer to an array of function pointers

8、 ... and 、 Callback function

1. introduce

2 . demonstration qsort Use of functions

3. VC & Delphi , Simulation Implementation qsort( By bubbling )

4. from qsort The principle of function to simulate

5. Use qsort Sort structure  

Nine 、sizeof() and strlen() The difference in array size

Ten 、 Pointer written test questions

Pen test 1

Pen test 2

Pen test 3

Pen test 4

Pen test 5

Pen test 6

Pen test 7

Pen test 8


One 、 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 = 'a';
	printf("%c\n", ch);
	return 0;
}
int main()
{
	const char* p = "abcdef";// Constant string cannot be modified directly 
	//*p = 'w';              //err   error 
	printf("%c\n", *p);      // Print a character 
	printf("%s\n", p);       // Print a string    Just give its first address 
	return 0;
}

  Another way to use it is as follows :

int main()
{
    const 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 const char* pstr = "hello bit."; It's especially easy to think of string hello bit . Put it in the character pointer pstr In the , But the essence is to put the string hello bit. The address of the first character Put it in pstr in .

Therefore, the above code means that the first character of a constant string h The address of is stored in the pointer variable pstr in .

Examples of interview questions :

int main()
{
	const char* p1 = "abcdef";  // And const irrelevant   It doesn't affect the answer 
	const char* p2 = "abcdef";

	char arr1[] = "abcdef";// Add do not add const The results are the same 
	char arr2[] = "abcdef";

	if (p1 == p2)
	{
		printf("p1 == p2\n");
	}
	else
	{
		printf("p1 != p2\n");
	}

	if (arr1 == arr2)
	{
		printf("arr1 == arr2\n");
	}
	else
	{
		printf("arr1 != arr2\n");
	}

	return 0;
}

The output is :

p1 == p2
arr1 != arr2

Two 、 Pointer array

Pointer array is an array of pointers . What does the following pointer array mean ?

int* arr1[10];  // Integer pointer array

char *arr2[4]; // First level character pointer array

char **arr3[5];// Second level character pointer array

int main()
{
	//int* arr[10];// An array of integer pointers 
	//char* ch[5]; // An array of character pointers 

	int a = 10;
	int b = 20;
	int c = 30;
	int* p1 = &a;
	int* p2 = &b;
	int* p3 = &c;

	int* arr[3] = { &a, &b, &c };//arr A pointer is an array 
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d ", *(arr[i]));
	}

	return 0;
}

  The output is :10  20  30  

int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[5] = { 2,3,4,5,6 };
	int arr3[5] = { 3,4,5,6,7 };

	int* parr[3] = { arr1, arr2, arr3 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", parr[i][j]);
			printf("%d ", *(parr[i]+j));
		}
		printf("\n");
	}

	return 0;
}

  Output results :

1 1 2 2 3 3 4 4 5 5
2 2 3 3 4 4 5 5 6 6
3 3 4 4 5 5 6 6 7 7

 int arr[5];
arr It's an array of integers , Each element is int Type of , Yes 5 Elements

int* parr1[10];
parr1 Is an array , Array 10 Elements , The type of each element is int*

int(*parr2)[10];
parr2 Is a pointer to an array , The array pointed to has 10 Elements , The type of each element is int

int(* parr3[10])[5];
parr3 Is an array , Array has 10 Elements , The type of each element is :int(*)[5]
parr3 Is an array that holds array pointers

  3、 ... and 、 Array pointer

1. Definition of array pointer

Array pointers are pointers ? Or arrays ? The answer is : The pointer .

int main()
{
	int a = 10;
	int *p = &a;    // Integer pointer  -  Pointer to an integer ,  The address of the integer variable 	
	char ch = 'w';
	char* pc= &ch;  // Character pointer  -  Pointer to character , Stored is the address of the character variable 
	return 0; 
}

The array pointer should be : A pointer to an array .

int *p1[10];

int (*p2)[10];

//p1, p2 What are the differences ?

explain :int (*p)[10];   

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 .

2.& Array name VS Array name

  How to understand array names ?

  Usually , The array name we are talking about is the address of the first element of the array
  But there are 2 Exceptions :
 1. sizeof( Array name ), The array name here represents the entire array ,sizeof( Array name ) It calculates the size of the entire array
 2. & Array name , The array name here represents the entire array ,& Array name , It takes out the address of the entire array

int main()
{
	int arr[10] = {0};
	// Array is the address of the first element 
	printf("%p\n", arr);
	printf("%p\n", arr+1);

	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0]+1);

	printf("%p\n", &arr);
	printf("%p\n", &arr+1);

	return 0;
}

  Output results :

0079F8E0
0079F8E4
0079F8E0
0079F8E4
0079F8E0
0079F908

3. The use of array pointers

Since the array pointer points to an array , The array pointer should store the address of the array .

#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
    return 0;
}

But we seldom write code like this .

Write a function to print arr Contents of array

// Write out the array with formal parameters 
void print1(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
// Formal parameters are written in the form of pointers 
void print1(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(arr + i));
	}
	printf("\n");
}
// This is not the recommended way to write 
void print1(int (*p)[10], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		//*p  Equivalent to array name , The array name is the address of the first element , therefore *p Namely &arr[0]
		printf("%d ", *(*p + i));
	}
	printf("\n");
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print1(arr, sz);
	return 0;
}

The use of an array pointer in a two-dimensional array :

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 .

void print2(int arr[3][5], int c, int r)
{
	int i = 0;
	for (i = 0; i < c; i++)
	{
		int j = 0;
		for (j = 0; j < r; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

void print2(int(*p)[5], int c, int r)
{
	int i = 0;
	for (i = 0; i < c; i++)
	{
		int j = 0;
		for (j = 0; j < r; j++)
		{
			//p+i Is pointing to the i Yes 
			//*(p+i) It's equivalent to getting the third i That's ok , Also equivalent to the second i Row array name 
			// The array name represents the address of the first element ,*(p+i)  That is the first. i The address of the first element of the line 
			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} };
	int (*ptr)[3][5] = &arr;    // Array pointer 
	print2(arr, 3, 5);
	return 0;
}

Four 、 Array parameters 、 Pointer parameter

1. One dimensional array parameters

#include <stdio.h>
void test(int arr[])// Yes 
{}
void test(int arr[10])// Yes 
// Array parameter passing is only the address of the first element   Does not create an array   So this 10 It's ok if there's any   No impact 
{}
void test(int *arr)// Yes 
{}
void test2(int *arr[20])// Yes    This 20 And the above one 
{}
void test2(int **arr)// Yes 
{}
int main()
{
     int arr[10] = {0};
     int *arr2[20] = {0};
     test(arr);
     test2(arr2);
}

2. Two dimensional array parameters

void test(int arr[3][5])// Yes 
{}
void test(int arr[][])// wrong 
{}
void test(int arr[][5])// Yes    Rows can be omitted, columns cannot be omitted 
{}
// 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)// wrong 
{}
void test(int* arr[5])// wrong 
{}
void test(int (*arr)[5])// Yes 
{}
void test(int **arr)// wrong 
{}
int main()
{
     int arr[3][5] = {0};
     test(arr);
}

The secondary pointer stores the address of the primary pointer , The array pointer stores the address of the array . 

3. First level pointer parameter transfer

void test(int* ptr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *ptr);
		ptr++;
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	test(p, sz);//p Is the first level pointer 
	return 0;
}
int main()
{
	int arr[3][5];
	test1(arr);// The address of the first line passed 
	test2(&arr);// What is passed is the address of the whole two-dimensional array 
	return 0;
}

  reflection : When the parameter part of a function is a first-order pointer , What parameters can a function take ?

such as :

void test1(int *p)
{}
//test1 What parameters can a function take ?
void test2(char* p)
{}
//test2 What parameters can a function take ?

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;
}

reflection : When the parameter of the function is a secondary pointer , What parameters can be received ?

void test(char **p)
{
 
}
int main()
{
     char c = 'b';
     char*pc = &c;
     char**ppc = &pc;
     char* arr[10];
     test(&pc);
     test(ppc);
     test(arr);//Ok?
     return 0;
}

5、 ... and 、 A function pointer

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

The output is :

00007FF7B2A913C0
00007FF7B2A913C0

The output is two addresses , These two addresses are test Address of function .

int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int arr[10];
	int (*p)[10] = &arr;//p Is an array pointer variable 
	printf("%p\n",  &Add);
	printf("%p\n", Add);
	int (* pf)(int, int) = Add;// Is a function pointer variable 
	int ret1 = (*pf)(2,3);
	int ret2 = Add(2, 3);

	int ret3 = pf(2, 3);
	printf("%d %d %d\n", ret1,ret2,ret3);
	return 0;
}

Output results :

005D11BD
005D11BD
5 5 5 

The address of our function should be saved , How to keep ?

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 store address , Should know pfun1 and pfun2 Is it 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 arguments , The return value type is void.

int main()
{ 
	// Code 1  ( *( void (*)() )0 )();

	void (*)()      // It's a function pointer type 
	void (*p)()
	( void (*)() )  //  (  type  )   The format is cast  
	( void (*)() )0 // Yes 0 Cast type conversion 
	//0x0012ff40
	
	( *( void (*)() )0 )();
	//1.  The first is to put 0 Cast type to a function pointer type , That means 0 Put a return type at the address, which is void, A function without parameters 
	//2.  call 0 This function at the address 


	int Add(int, int);  // Function type declaration 

	// Code 2
	void (* signal(int, void(*)(int)) )(int); // Function declaration 

	typedef void(* pf_t)(int) ;// Give the function pointer type void(*)(int) Renamed :pf_t
	pf_t signal(int, pf_t);    // Then it's converted to this 

	//signal Is a function declaration 
	//signal The parameters of the function , The first is int Type of , The second is void(*)(int) Function pointer type of 
	//signal The return value type of the function is also :void(*)(int) Function pointer of 

	return 0;
}

6、 ... and 、 Function pointer array

To store 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 .

Purpose of function pointer array : Transfer table

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()
{
	char* arr[5];  // Character pointer array 
	int* arr2[4];  // Integer pointer array 

	int (*pf1)(int, int) = Add;
	int (*pf2)(int, int) = Sub;
	int (*pf3)(int, int) = Mul;
	int (*pf4)(int, int) = Div;
	// Function pointer array 
	int (* pf[4])(int, int) = { Add, Sub, Mul, Div };
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		int ret = pf[i](8, 2);
		printf("%d\n", ret);
	}

	return 0;
}
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 menu()
{
	printf("**************************\n");
	printf("****  1.add   2.sub   ****\n");
	printf("****  3.mul   4.div   ****\n");
	printf("****  0.exit          ****\n");
	printf("**************************\n");
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;

	do
	{
		menu();
		printf(" Please select :>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf(" Please enter 2 Operands :>");
			scanf("%d%d", &x, &y);
			ret = Add(x, y);
			printf("ret = %d\n", ret);
			break;
		case 2:
			printf(" Please enter 2 Operands :>");
			scanf("%d%d", &x, &y);
			ret = Sub(x, y);
			printf("ret = %d\n", ret);
			break;
		case 3:
			printf(" Please enter 2 Operands :>");
			scanf("%d%d", &x, &y);
			ret = Mul(x, y);
			printf("ret = %d\n", ret);
			break;
		case 4:
			printf(" Please enter 2 Operands :>");
			scanf("%d%d", &x, &y);
			ret = Div(x, y);
			printf("ret = %d\n", ret);
			break;
		case 0:
			printf(" Exit calculator \n");
			break;
		default:
			printf(" Wrong choice \n");
			break;
		}
	} while (input);

	return 0;
}

Use Function pointer array The implementation of the :

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 menu()
{
	printf("**************************\n");
	printf("****  1.add   2.sub   ****\n");
	printf("****  3.mul   4.div   ****\n");
	printf("****  0.exit          ****\n");
	printf("**************************\n");
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	// Transfer table 
	int (*pfArr[])(int, int) = {0, Add, Sub, Mul, Div};
 
	do
	{
		menu();
		printf(" Please select :>");
		scanf("%d", &input);
		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("ret = %d\n", ret);
		}
		else
		{
			printf(" Wrong choice \n");
		}

	} while (input);

	return 0;
}

7、 ... and 、 A pointer to an array of function pointers

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

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;
}
int main()
{
	int arr[10] = {1,2,3,4,5,6,7};
	int(*p)[10] = &arr;//p You have to be an array pointer 

	// A function pointer 
	int (*pf)(int, int) = &Add;

	// Function pointer array 
	int (* pfarr[4])(int, int);
	int (* (*p3)[4])(int, int) = &pfarr;//p3 Is a pointer to an array of function pointers 

	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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()
{
	// Function pointer array 
	int (*pfarr[4])(int, int) = {Add,Sub,Mul,Div};
    //p3 Is a pointer to an array of function pointers 
	int (*(* p3)[4])(int, int) = &pfarr;
    int i =0;
	for (i = 0; i < 4; i++)
	{
		//*p
		//*(p3+0)
		//p3[0]
		int ret = p3[0][i](3, 4);   //int ret = (*p3)[i](3,4);
		printf("%d\n", ret);
	}
	return 0;
}

  8、 ... and 、 Callback function

1. introduce

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 .

void test()
{
	printf("hehe\n");
}

void print_hehe(void (*p)())  //p Is a function pointer 
{
	if (1)
		p();
}

int main()
{
	print_hehe(test);
	return 0;
}
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 menu()
{
	printf("**************************\n");
	printf("****  1.add   2.sub   ****\n");
	printf("****  3.mul   4.div   ****\n");
	printf("****  0.exit          ****\n");
	printf("**************************\n");
}

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);
	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(" Wrong choice \n");
			break;
		}
	} while (input);

	return 0;
}

2 . demonstration qsort Use of functions

void qsort(void* base, 
           size_t num, 
         size_t width, 
    int(*cmp)(const void* e1, const void* e2)// A function pointer
           );

#include <stdio.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;
}

3. VC & Delphi , Simulation Implementation qsort( By bubbling )

void bubble_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz-1-i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

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 };
	// Sort in ascending order 
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	print_arr(arr, sz);
}
int main()
{
	test1();
	return 0;
}

4. from qsort The principle of function to simulate

#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);
       *(( char *)p2 + i) = tmp;
    }
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
    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 };
    //char *arr[] = {"aaaa","dddd","cccc","bbbb"};
    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;
}

5. Use qsort Sort structure  

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

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)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

void test3()
{
	struct Stu arr[3] = { {"zhangsan", 20, 55.5},{"lisi", 30, 88.0},{"wangwu", 10, 90.0} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
	qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}

int main()
{
	test3();
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

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)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

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++;
	}
}

void bubble_sort(void* base, int num, int width, int (*cmp)(const void* e1, const void* e2))
{
	int i = 0;
	for (i = 0; i < num - 1; i++)
	{
		int j = 0;
		for (j = 0; j < num - 1 - i; j++)
		{
			//if (arr[j] > arr[j + 1]) // Compare 
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
			{
				// In exchange for 
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
			}
		}
	}
}

void test5()
{
	struct Stu arr[3] = { {"zhangsan", 20, 55.5},{"lisi", 30, 88.0},{"wangwu", 10, 90.0} };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}

int main()
{
	test5();
	return 0;
}

   Nine 、sizeof() and strlen() The difference in array size

sizeof Is an operator
sizeof The calculation is the size of the memory occupied by the object - Unit is byte ,size_t
Don't care what's stored in memory , Only care about memory size

strlen Library function
Find the string length , Access characters backwards from a given address , Statistics \0 The number of characters that appear before

#include <stdio.h>
#include <string.h>
int main()
{
	// One dimensional array 
	int a[] = { 1,2,3,4 };
	int (*p)[4] = &a;
	printf("%d\n", sizeof(a));//4*4 = 16
	printf("%d\n", sizeof(a + 0));//4/8 a+0 Is the address of the first element of the array , It's the address , Size is 4/8 Bytes 
	printf("%d\n", sizeof(*a)); //4 a Represents the address of the first element of the array ,*a Represents the first element of the array ,sizeof(*a) Is the size of the first element -4
	printf("%d\n", sizeof(a + 1));//4/8 a Represents the address of the first element of the array ,a+1 The address of the second element of the array ,sizeof(a+1) Is the size of the address of the second element 
	printf("%d\n", sizeof(a[1]));//4  It calculates the size of the second element 
	printf("%d\n", sizeof(&a));//4/8 &a What we get is the address of the array , The address of the array is also the address , Yes, the address size is 4/8 byte 
	printf("%d\n", sizeof(*&a));//16  Calculate the size of the entire array  
	printf("%d\n", sizeof(&a + 1));//4/8 - &a Is the address of the array ,+1 Skip the entire array , Produced 4 The address of the back position 
	printf("%d\n", sizeof(&a[0]));//4/8  The address of the first element of the extracted array 
	printf("%d\n", sizeof(&a[0] + 1));//4/8  The address of the second element of the array 

	// A character array 
	char arr[] = { 'a','b','c','d','e','f' };//[a b c d e f]
	printf("%d\n", strlen(arr));// Random value ,arr There is no \0, therefore strlen The function will continue to look back \0, Statistics \0 The number of characters that appear before 
	printf("%d\n", strlen(arr + 0));// Random value ,arr+0 The address of the first element of the array 
	//printf("%d\n", strlen(*arr));  //err error 
	//arr Is the address of the first element of the array ,*arr Is the first element of the array ,‘a’-97
	//printf("%d\n", strlen(arr[1]));  //err  error 
	//'b' - 98
	printf("%d\n", strlen(&arr));// Random value 
	printf("%d\n", strlen(&arr + 1));// Random value 
	printf("%d\n", strlen(&arr[0] + 1));// Random value 

	//Unsigned long long  ->llu
	printf("%llu\n", sizeof(arr));//6  
	printf("%llu\n", sizeof(arr + 0));//4/8 arr + 0 Is the address of the first element of the array 
	printf("%llu\n", sizeof(*arr));//1 - *arr It's the first element , The first element is a character , The size is one byte 
	printf("%llu\n", sizeof(arr[1]));//1 - arr[1] Is the second element of the array , Size is 1 Bytes 
	printf("%llu\n", sizeof(&arr));//4/8 &arr Is the address of the array 
	printf("%llu\n", sizeof(&arr + 1));//4/8 &arr + 1 It is an address generated by skipping the whole array back from the array address 
	printf("%llu\n", sizeof(&arr[0] + 1));//4/8 &arr[0] + 1  Is the address of the second element of the array 

	return 0;
}
#include <stdio.h>
#include <string.h>

int main()
{
	char arr[] = "abcdef";
	//[a b c d e f \0]

	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
	//printf("%d\n", strlen(*arr));   //err error 
	//printf("%d\n", strlen(arr[1])); //err error 
	//printf("%d\n", strlen(&arr));//6
	//printf("%d\n", strlen(&arr + 1));// Random value 
	printf("%d\n", strlen(&arr[0] + 1));//5

	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//4/8 arr+0 Is the address of the first element of the array 
	printf("%d\n", sizeof(*arr));//1 - *arr  The first element of an array 
	printf("%d\n", sizeof(arr[1]));//1 arr[1] The second element of the array 
	printf("%d\n", sizeof(&arr));//4/8 - &arr Address of array , But the address of the array is still the address , Yes, the address size is 4/8
	printf("%d\n", sizeof(&arr + 1));//4/8 - &arr + 1 yes \0 The address in the back 
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 - &arr[0] + 1 Is the address of the second element of the array 

	const char* p = "abcdef";

	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5  from b The position of the starts with the backward number character 
	//printf("%d\n", strlen(*p));  //err
	//printf("%d\n", strlen(p[0]));//err
	//printf("%d\n", strlen(&p));// Random value 
	//printf("%d\n", strlen(&p + 1));// Random value 
	printf("%d\n", strlen(&p[0] + 1));//5   from b The position of the starts with the backward number character 

	printf("%d\n", sizeof(p));//4/8  p It's a pointer variable , It calculates the size of the pointer variable 
	printf("%d\n", sizeof(p + 1));//4/8 p+1 yes 'b' The address of 
	printf("%d\n", sizeof(*p)); //1  - *p  In fact, that is 'a'
	printf("%d\n", sizeof(p[0]));//1 - p[0]-> *(p+0)-> *p
	printf("%d\n", sizeof(&p));//4/8 &p  It's a pointer variable p Address in memory 
	printf("%d\n", sizeof(&p + 1));//4/8 - &p+1 It's skipping p Address after 
	printf("%d\n", sizeof(&p[0] + 1));//4/8 &p[0] yes ‘a’ The address of ,&p[0]+1 Namely b The address of 

	// Two dimensional array 
	int a[3][4] = { 0 };

	printf("%d\n", sizeof(a));// It calculates the size of the entire array , Unit is byte 3*4*4 = 48
	printf("%d\n", sizeof(a[0][0]));//4  The first 1 The size of the first element of the line 
	printf("%d\n", sizeof(a[0]));//16 - a[0] Is the array name in the first row ,
	//sizeof(a[0]) On the first line of the array is the list sizeof Inside , It calculates the size of the first line 
	printf("%d\n", sizeof(a[0] + 1));
	//4/8 a[0] As the array name of the first row , Not alone in sizeof Inside , No address was taken 
	// therefore a[0] Is the address of the first element of the array , Is the address of the first element in the first line ,a[0]+1 Is the address of the second element in the first line 

	printf("%d\n", sizeof(*(a[0] + 1)));
	//4 - *(a[0] + 1)) It represents the second element in the first line 
	printf("%d\n", sizeof(a + 1));
	//4/8 - a Represents the address of the first element ,a Is a two-dimensional array , The address of the first element is the address of the first line 
	// therefore a It represents the address of the first row of the two-dimensional array ,a+1 It's the address on the second line 
	printf("%d\n", sizeof(*(a + 1)));//16  Dereference the address of the second line and access the second line 
	//*(a+1) -> a[1]
	//sizeof(a[1])
	
	printf("%d\n", sizeof(&a[0] + 1));//4/8 - a[0] Is the array name in the first row ,&a[0] What you take out is the address in the first line 
	//&a[0] + 1  It's the address on the second line 

	printf("%d\n", sizeof(*(&a[0] + 1)));//16 -  Dereference the address of the second line and access the second line 
	printf("%d\n", sizeof(*a));//16 - a Is the address of the first element , It's the address on the first line ,*a It's the first line 
	//*a - > *(a+0) -> a[0]

	printf("%d\n", sizeof(a[3]));//16 int [4]

	int n = 10;
	printf("%d\n", sizeof(a));//4
	printf("%d\n", sizeof(int));//4

	return 0;
}

Ten 、 Pointer written test questions

Pen test 1

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}

  The output is :2, 5

Pen test 2

// Because I haven't learned the structure yet , The size of the structure is 20 Bytes 
struct Test
{
     int Num;
     char *pcName;
     short sDate;
     char cha[2];
     short sBa[4];
}*p;
// hypothesis p  The value of is 0x100000.  What are the values of the expressions in the following table ?
// It is known that , Structure Test The variable size of type is 20 Bytes 
int main()
{
     printf("%p\n", p + 0x1);
     printf("%p\n", (unsigned long)p + 0x1);
     printf("%p\n", (unsigned int*)p + 0x1);
     return 0;
}

  The output is :

0000000000000020
0000000000000001
0000000000000004

Pen test 3

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0;
}

Output results : 4    2000000

  Pen test 4

#include <stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0];
    printf( "%d", p[0]);
    return 0;
}

  Pen test 5

int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

  Pen test 6

int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int *ptr1 = (int *)(&aa + 1);
    int *ptr2 = (int *)(*(aa + 1));
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

Output results :10,5

  Pen test 7

int main()
{
     char *a[] = {"work","at","alibaba"};
     char**pa = a;
     pa++;
     printf("%s\n", *pa);
     return 0;
}

  Pen test 8

int main()
{
     char *c[] = {"ENTER","NEW","POINT","FIRST"};
     char**cp[] = {c+3,c+2,c+1,c};
     char***cpp = cp;
     printf("%s\n", **++cpp);
     printf("%s\n", *--*++cpp+3);
     printf("%s\n", *cpp[-2]+3);
     printf("%s\n", cpp[-1][-1]+1);
     return 0;
}

版权声明
本文为[Tea rainbow]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231532440107.html