当前位置:网站首页>[C language] advanced pointer --- do you really understand pointer?
[C language] advanced pointer --- do you really understand pointer?
2022-07-07 21:18:00 【Pigskin brother】
🧸🧸🧸 Hello everyone , I'm pig skin brother 🧸🧸🧸
Here is the following knowledge content 🥳🥳🥳
Preface
What we are learning today is Advanced pointer .
One 、 Classification of knowledge points
Today's advanced pointer includes character pointer , Array pointer , Pointer array , Array parameter passing and pointer parameter passing , A function pointer , Function pointer array , A pointer to an array of function pointers , Callback functions, etc .
Two 、 The ginseng
1. One dimensional array parameters
// Formal parameters can be written in the form of arrays and pointers
// Real arrays will not be created here , So there is no need to write any size here
// Because only the address of the first element of the array is passed
void test1(int arr[10]);
void test1(int arr[]);
void test1(int *arr);
void test2(int**arr);
void test2(int*arr[]);
int main()
{
int arr1[10]={
0};
int*arr2[20]={
0};
test1(arr1);
test2(arr2);
return 0;
}
2. Pass parameters of two-dimensional array
The first element of a two-dimensional array actually represents the address of the first row
1. Formal parameters are written in the form of arrays
test(int arr[3][5]); Because it's the address in the first line , So here 3 It doesn't make sense , Just columns ( Columns cannot be omitted )
2. Formal parameters are written as pointers
void test(int (*p)[5]);
This is an array pointer ,*p Means it is a pointer ,[5] Represents that this array has five elements ,int The type representing each element is int
It must not be written as void test(int(*p)[3][5]); This represents the entire two-dimensional array , And the address of the first line is only needed for parameter transmission
3、 ... and 、 Various pointers and arrays
1. Special examples of array names
The array name usually represents the address of the first element , But there are two exceptions
1.sizeof( Array name ):sizeof The size of the whole array is calculated with a single array name .
2.& Array name :& Followed by a separate array name, the address of the entire array is taken
2. A function pointer
A function pointer –> Pointer to function
The form of function pointer :
Like functions
int Add(int x,int y)
Then the function pointer is
int (*pf)(int,int);
int Add(int x,int y)
{
return x+y;
}
int test(char*str)
{
}
int main()
{
int arr[10];
int(*p)[10]=&arr;
printf("%p\n",&Add);
printf("%p\n",Add);// It can be explained that Add and &Add The address of is the same
// The writing is different , But the meaning is the same , All we get is the address of the function
int(*pf)(int,int)=Add;
// Equate to
//int(*pf)(int,int)=&Add;
int ret=(*pf)(2,3);
//int ret=(********pf)(2,3);
//int ret=Add(2,3);
// there pf That's the function pointer
int(*pf2)(char*)=test;//&test
printf("%d\n",(*pf)(2,3));
printf("%d\n",ret);
return 0;
}
Explanation of function pointer examples
int main()
{
//1.
(*(void(*)())0)();
//void(*)() Is the type of a function pointer
//(void(*)())0 That is the 0 Cast the type to such a function pointer
// signify 0 There is such a function at the address , Which function has the address 0( Here knowledge assumes access 0 This address )
// The application is not accessible 0 At this address
// and int (*pf)(int,int)=Add; analogy , That is to say pf A function is placed at
// Then dereference this address *(void(*)())0 Find this function , Call again *(void(*)())0()
//2.
void (*signal(int, void(*)(int)))(int);
//void(*)(int) yes signal Second parameter of , Is a function pointer
//signal The return type of a function is a function pointer
}
3. 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()
{
// Pointer array
// Character pointer array
char*arr[5];
// Array of integer pointers
int*arr2[4];
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};
printf("%d",pf[0](1,2));
return 0;
// First, pf[4] Represents an array , The size is 4
// The type of each element is int (*)(int,int);
}
4. The function pointer array implements the arithmetic unit
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 ***\n");
printf("*** 2.Sub ***\n");
printf("*** 3.Mul ***\n");
printf("*** 4.Div ***\n");
printf("*** 0.Exit ***\n");
}
// Implement calculator
int main()
{
int input;
int x,y;
int ret;
int (*pf[5])(int,int) = (0,Add,Sub,Mul,Div);
// This initialization is because the array is from 0 At the beginning
do
{
menu();
printf(" Please select :>");
scanf("%d\n",&input);
if(input==0)
{
printf(" Exit calculator .....\n");
break;
}
else if(input>=1&&input<=4)
{
printf(" Please enter two operands :>");
scanf("%d %d",&x,&y);
ret=pf[input](x,y);
printf("ret=%d\n",ret);
}
else
{
printf(" Wrong choice \n");
}
}while(input);
return 0;
}
3、 ... and 、 Callback function and qsort function
1. Callback function
Concept :
A callback function is a function called through a function pointer . If you pass the pointer of a function, that is, the address, 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 called directly by the function's implementer , It's called by another party when a particular event or condition occurs , Used to respond to time or conditions .
A The address of the function is passed to B function , stay B Functions are called callback functions
void test()
{
printf("zhupi\n");
}
void print_zhupi(void(*pf)())
{
if( A condition )// If a certain condition or time occurs , The response
pf();
}
int main()
{
print_zhupi(test);
return 0;
}
Use the callback function to complete the calculator
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 (*pf)(int,int))
{
int x,y;
int ret=0;
printf(" Please enter two operands :>");
scanf("%d %d",&x,&y);
ret=pf(x,y);
printf("%d\n",ret);
}
void menu()
{
printf("********************\n");
printf("*** 1.Add ***\n");
printf("*** 2.Sub ***\n");
printf("*** 3.Mul ***\n");
printf("*** 4.Div ***\n");
printf("*** 0.Exit ***\n");
}
// Implement calculator
int main()
{
int input;
int x,y;
int ret;
int (*pf[5])(int,int) = (0,Add,Sub,Mul,Div);
// This initialization is because the array is from 0 At the beginning
do
{
menu();
printf(" Please select :>");
scanf("%d\n",&input);
switch(input)
{
case 1:
calc(Add);
break;
case 2:
calc(Sub);
break;
case 3:
calc(Mul);
break;
case 1:
calc(Div);
break;
case 0:
exit(-1);
}
return 0;
}
2.qsort function
qsort Function is a library function , It is a sorting function based on quick sorting algorithm
qsort The header file to be quoted is #include <stdlib.h>
qsort This function can sort any type of data
Functions written by ourselves may not be able to
For example, our bubble sort
void bubble_sort(int arr[],int len)
{
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-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 len=sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,len);
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
// It can be seen that , Not universal
qsort:
qsort The sorting function defined in the needs to return >0 <0 =0 The number of , After getting the result qsort You can sort according to the returned number
Right now qsort Parameters of
void qsort(void*base,
size_t num,
size_t width,
int(*cmmp)(const void*e1,const void*e2));
//base Is the actual location of the data to be sorted
//num Is the number of elements of the array
//width Is the size of each element
//elem1 elem2 Is the address of the two elements to be compared
// This comparison function requires qsort The user of the function customizes a comparison function
// Because the element types are different , Users according to the actual situation , Provide a comparison function
give an example =>
int cmp_int(const void*e1,const void*e2)
{
//void* Is a pointer without an exact type , Cannot dereference directly
// Because the type of pointer represents the permission to access several bytes when dereferencing , and void* It's not clear ;
//void* It's a garbage can , Any type can be put in , Then it's OK to force type conversion ;
//1.
if(*(int*)e1>*(int*)e2)
{
return 1;
}
else if(*(int*)e1<*(int*)e2)
{
return -1;
}
else
{
return 0;
}
//2.
return (*(int*)e1-*(int*)e2;
}
void test()
{
int arr[]={
9,8,7,6,5,4,3,2,1,0};
int len=sizeof(arr)/sizeof(arr[0]);
qsort(arr,len,sizeof(arr[0]),cmp_int);
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
}
int main()
{
test();
return 0;
}
Use qsort Sort structure
struct Stu
{
char mame[20];
int age;
double score;
};
int cmp_stu_by_name(const void*e1,const void*e2)
{
return strcmp(((struct Stu*)e1)->mame, ((struct Stu*)e2)->mame);
}
void test()
{
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_name);
}
int main()
{
test();
return 0;
}
3. General bubble sort
int cmp_int(const void* e1, const void* e2)// Compare what you decide
{
return *(int*)e1 - *(int*)e2;
}
void Swap(char*buf1,char*buf2,int width)
{
for (int i = 0; i < width; i++)
{
char temp = *buf1;
*buf1 = *buf2;
*buf2 = temp;
buf1++;
buf2++;
}
// Byte by byte exchange
}
void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* e1, const void* e2))
{
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1 - i; j++)
{
// Compare , Because I know the width of each element , So cast the type to char*
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 print_arr(int * base, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ",*(base+i));
}
}
void test2()
{
int arr[] = {
9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr,sz);
}
int main()
{
test2();
return;
}
Four 、 Various sizeof and strlen The calculation of !!!
1. One dimensional array
int main()
{
int a[] = {
1,2,3,4 };
printf("%d\n",sizeof(a));//16
printf("%d\n",sizeof(a+0));//4/8, What is in parentheses is not a separate array name , So it represents the address of the first element , An address is a pointer
printf("%d\n",sizeof(*a));//4 Not a separate array name , therefore a Represents the address of the first element , Quoting , It's the first element
printf("%d\n",sizeof(a+1));//4/8 It calculates 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 Take out Is the address of the array , The address of the array is also the address , It's the address ( The pointer ) Size is 4/8 Bytes
printf("%d\n",sizeof(*&a));//16 &a It takes out the address of the entire array , Then dereference to get the whole array , So we calculate the size of the whole array
printf("%d\n",sizeof(&a+1));//4/8 &a What you get is the address of the whole array ,+1 Is to skip the entire array , But it's also the address
printf("%d\n",sizeof(&a[0]));//4/8 Represents the address of the first element
printf("%d\n",sizeof(&a[0]+1));//4/8 Represents the address of the second element
return 0;
}
2. A character array
int main()
{
char arr[] = {
'a','b','c','d','e','f'};
printf("%d\n",sizeof(arr));//6
printf("%d\n",sizeof(arr+0));//4/8
printf("%d\n",sizeof(*arr));//1
printf("%d\n",sizeof(arr[1]));//1
printf("%d\n",sizeof(&arr));//4/8
printf("%d\n",sizeof(&arr+1));//4/8
printf("%d\n",sizeof(&arr[0]+1));//4/8
return 0;
}
int main()
{
char arr[] = {
'a','b','c','d','e','f' };
//strlen Look for the end expression \0
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
printf("%d\n",strlen(*arr));//error arr Is the address of the first element of the array ,*arr Is the first element of the array ,'a'-97,strlen hold 97 As an address , From this address
// Look back \0, There may be wild pointer problems , Error accessing memory , So the code itself is wrong , Did not get a valid address
// In the eyes of pointer variables , Everything is an address , Because the meaning of his natural existence is to store addresses
printf("%d\n",strlen(arr[1]));//error
printf("%d\n",strlen(&arr));// Random value , look for \0
printf("%d\n",strlen(&arr+1));// Random value
printf("%d\n",strlen(&arr[0]+1));// Random value
return 0;
}
int main()
{
char arr[] = "abcdef";
printf("%d\n",sizeof(arr));//7
printf("%d\n",sizeof(arr+0));//4/8
printf("%d\n",sizeof(*arr));//1
printf("%d\n",sizeof(arr[1]));//1
printf("%d\n",sizeof(&arr));//4/8
printf("%d\n",sizeof(&arr+1));//4/8
printf("%d\n",sizeof(&arr[0]+1));//4/8
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//error
printf("%d\n", strlen(arr[1]));//error
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));// Random value
printf("%d\n", strlen(&arr[0] + 1));//5
return 0;
}
int main()
{
char* p = "abcdef";// Constant string
//p yes 'a' The address of
printf("%d\n",sizeof(p));//4/8
printf("%d\n",sizeof(p+1));//4/8 p+1 yes 'b' The address of
printf("%d\n",sizeof(*p));//18
printf("%d\n",sizeof(p[0]));//1
printf("%d\n",sizeof(&p));//4/8 &p Is the address of the pointer , Double pointer
printf("%d\n",sizeof(&p+1));//4/8
printf("%d\n",sizeof(&p[0]+1));//4/8
printf("%d\n",strlen(p));//6
printf("%d\n",strlen(p+1));//5
printf("%d\n",strlen(*p));//error
printf("%d\n",strlen(p[0]));//error
printf("%d\n",strlen(&p));// Random value
printf("%d\n",strlen(&p+1));// Random value
printf("%d\n",strlen(&p[0]+1));//5
return 0;
}
3. Two dimensional array
int main()
{
int a[3][4] = {
0 };
printf("%d\n",sizeof(a));//48 sizeof( Array name ) It calculates the size of the entire array
printf("%d\n",sizeof(a[0][0]));//4
printf("%d\n",sizeof(a[0]));//16 a[0] yes *(a+0) Is the address of the first element in the first line , That is, the array name in the first line , therefore sizeof(a[0]) In fact, it calculates the size of the first row
printf("%d\n",sizeof(a[0]+1));//4/8 a[0] Is the array name in the first row ,a[0]+1 That is, the address of the second element in the first line
printf("%d\n",sizeof(*(a[0]+1)));//4 That is to say a[0][1]
printf("%d\n",sizeof(a+1));//4/8 The array name of a two-dimensional array represents the address of the first line , therefore a+1 It represents the address in the second line
printf("%d\n",sizeof(*(a+1)));//16 a+1 Is the address on the second line , After dereference, the address of the first element in the second line , So we're calculating the size of the second line
printf("%d\n",sizeof(&a[0]+1));//4/8 It represents the address in the second line
printf("%d\n",sizeof(*(&a[0]+1)));//16 The parentheses indicate the address of the first element in the second line That is, the array name in the second line , It calculates the size of the second row of the array
printf("%d\n",sizeof(*a));//16 The address of the first row array is calculated
printf("%d\n",sizeof(a[3]));//16 a[3] Is the address of the first element in the fourth line
return 0;
}
5、 ... and 、 5、 ... and The color spot Beautiful Of One some Scrap word
When you see here , I believe the above content has been memorized ️️️. If you find it helpful , Use your little hand to point . Is there a problem with one button three times ? No problem , What are these ? traditional code of conduct . It's not easy to create , Support a lot .
边栏推荐
- FTP steps for downloading files from Huawei CE switches
- 恶魔奶爸 指南帖——简易版
- 寫一下跳錶
- UVA 12230 – crossing rivers (probability) "suggested collection"
- [function recursion] do you know all five classic examples of simple recursion?
- Jetty: configure connector [easy to understand]
- 201215-03-19 - cocos2dx memory management - specific explanation "recommended collection"
- CodeSonar通过创新型静态分析增强软件可靠性
- Description of the difference between character varying and character in PostgreSQL database
- Codeforces round 296 (Div. 2) A. playing with paper[easy to understand]
猜你喜欢
Static analysis of software defects codesonar 5.2 release
【OpenCV 例程200篇】223. 特征提取之多边形拟合(cv.approxPolyDP)
Cantata9.0 | 全 新 功 能
Focusing on safety in 1995, Volvo will focus on safety in the field of intelligent driving and electrification in the future
Tensorflow2.x下如何运行1.x的代码
How does codesonar help UAVs find software defects?
Klocwork code static analysis tool
软件缺陷静态分析 CodeSonar 5.2 新版发布
程序猿赚的那点钱算个P啊!
Apifox interface integrated management new artifact
随机推荐
Devil daddy B1 hearing the last barrier, break through with all his strength
The difference between NPM uninstall and RM direct deletion
恶魔奶爸 A0 英文零基础的自我提升路
object-c编程tips-timer「建议收藏」
死锁的产生条件和预防处理[通俗易懂]
Codeforces 474 F. Ant colony
[UVALive 6663 Count the Regions] (dfs + 离散化)[通俗易懂]
Codeforces 474 F. Ant colony
AADL inspector fault tree safety analysis module
Object-C programming tips timer "suggestions collection"
Écrivez une liste de sauts
HOJ 2245 浮游三角胞(数学啊 )
C language helps you understand pointers from multiple perspectives (1. Character pointers 2. Array pointers and pointer arrays, array parameter passing and pointer parameter passing 3. Function point
Focusing on safety in 1995, Volvo will focus on safety in the field of intelligent driving and electrification in the future
How does codesonar help UAVs find software defects?
2022年在启牛开中银股票的账户安全吗?
Measure the height of the building
Default constraint and zero fill constraint of MySQL constraint
Do you have to make money in the account to open an account? Is the fund safe?
MinGW MinGW-w64 TDM-GCC等工具链之间的差别与联系「建议收藏」