当前位置:网站首页>C language pointer
C language pointer
2022-06-11 03:07:00 【shlyyy】
C Language pointer
Preface
I am learning C Language pointer related content , Include pointer array 、 Array pointer 、 A function pointer , Always confused , And learn to forget , Forget to learn , Go back and forth . My understanding of this part is summarized as follows .
If you can understand why the following code is written , There is no need to waste time reading this article .
int main(int argc, char* argv[])
{
int ary1[4] = {
1,2,3,4 };
int *p1 = ary1;
int(*p2)[4] = &ary1;
int nAry[2][4] = {
{
10,20,30,40},
{
60,70,80,90}
};
int(*p3)[4] = nAry;
int (*p4)[2][4] = &nAry;
return 0;
}
(*(void(*)())0)();
void (*signal(int, void(*)(int n)))(int n);
int main(int argc, char* argv[])
{
int(*pfun[2])(int a, int b);
int(**pPfun)(int a, int b) = pfun;
return 0;
}
int main(int argc, char* argv[])
{
int(*pfun[2])(int a, int b);
int(*(*pPfun)[2])(int a, int b) = &pfun;
return 0;
}
One 、 Array recognition
1.1 One dimensional array subscript operation ([])
The result of the subscript operation gets a reference to its element .
Subscript operation requires an operand of integer type , The other operand is the address .
int main(int argc, char* argv[])
{
int ary[5] = {
1, 2 };
// &2[ary] = &ary[2];
printf("%p\r\n", &ary[2]); // 0019FED0
printf("%p\r\n", &2[ary]); // 0019FED0
system("pause");
return 0;
}
*(arr + n) = arr[n]
int main(int argc, char* argv[])
{
int ary[5] = {
5,4,3,2,1 };
int* ptr = (int*)(&ary + 1);
printf("%d\n", *(ptr - 1)); // 1
return 0;
}
&ary in ary Represents the entire array , therefore ptr Pointing to the array ary After the last element of the , That is, skip the array ary.
1.2 One dimensional array addressing mode
Addressing mode of one-dimensional array :
type ary[M] = …; ary[n] address is:(int)ary + sizeof(type) * n
int main(int argc, char* argv[])
{
int ary[2] = {
0 };
// 0x400000 Situated MZ identification
printf("%p\r\n", (void*)ary[(0x400000 - (int)ary) / sizeof(int)]); // 00905A4D
printf("%s\r\n", (char*)&ary[(0x400000 - (int)ary) / sizeof(int)]); // MZ?
system("pause");
return 0;
}
1.3 Two dimensional array
Two dimensional arrays are special one-dimensional arrays , Array elements are arrays of one-dimensional arrays
int ary[2][3] = {
{
1,2,3}, // ary[0]
{
4,5,6} // ary[1]
};
// ary There are two elements , Each element is int[3] type
int[3] ary[2] = {
{
1,2,3},
{
4,5,6}
};
// Two subscript operations , The first subscript operation yields ary[1], For a one-dimensional array 3 Elements
// The second subscript operation starts from ary[1] Take the th... From the one-dimensional array of 2 Elements get data
ary[1][2];
Two dimensional array addressing mode
type ary[N][M] = ...;
int x,y = ...;
ary[x][y] address is:
(int)ary + sizeof(type[M])*x + sizeof(type)*y
==> (int)ary + sizeof(type)*M*x + sizeof(type)*y
==> (int)ary + sizeof(type)*(M*x + y)
ary[0][M*x + y] <==> ary[x][y]
*(arr + n) = arr[n]
int main(int argc, char* argv[])
{
int ary[2][5] = {
10,9,8,7,6,5,4,3,2,1 };
int* ptr1 = (int*)(&ary + 1);
int* ptr2 = (int*)(*(ary + 1));
printf("%d,%d\n", *(ptr1 - 1), *(ptr2 - 1)); // 1 6
return 0;
}
&ary in ary Represents the entire array , therefore ptr1 Pointing to the array ary After the last element of the , That is, skip the array ary.
Array name ary Represents the address of the first element , That is to say ary[0] The address of ,*(ary + 1) = ary[1], therefore ptr2 Point to ary[1].
1.4 summary
- except
sizeof(arr)and&arrArray name inarr, Array names that appear elsewherearr, Are the address of the first element of the array .- *(arr + n) = arr[n]
Two 、 The pointer
A pointer is a variable , The address where the memory unit is stored . Indirect operation of memory unit through pointer , The type of pointer determines whether the pointer moves forward or backward ( Pointer addition and subtraction 1) How big is the , And the pointer type determines how the pointer is interpreted ( Dereference the pointer *).
In conclusion , The pointer = Address + Mode of interpretation
2.1 int* pa, p;
int main(int argc, char* argv[])
{
int ary[4] = {
1,2,3,4 };
int* pa, p; // pa For the pointer ,p Is an integer .
pa = ary;
p = ary; // “=”:“int” And “int *” Different levels of indirection
return 0;
}
2.2 Pointer arithmetic
1. Pointer plus integer gets pointer constant of the same type
2. Subscript the pointer , Get variable references to pointer types
3. Pointers of the same type can be subtracted , The result is an integer constant
type *p = ...;
int n = ...;
// 1. Pointer plus integer gets pointer constant of the same type
p + n = (int)p + n*sizeof(type);
// 2. Subscript the pointer , Get variable references to pointer types
p[n] = *(type*)((int)p + n*sizeof(type));
type *p1 = ...;
type *p2 = ...;
// 3. Pointers of the same type can be subtracted , The result is an integer constant
p1 - p2 = ((int)p1 - (int)p2) / sizeof(type);
2.3 *p++ And *++p
* With the priority of ++ Same priority for , The priority is 2, And they are all combined from right to left .
*p++: First, execute p++, But post ++ After the whole statement is executed p Again ++. And then execute *p Value . Last p+=1.
Equate to *p;p+=1;
void mystrcpy(char* szDst, char* szSrc)
{
while(*szDst++ = *szSrc++);
}
*++p: From right to left ,++p Execute first , After execution p Updated to p+1, And then take the value .
Equate to :p+=1;*p;
2.4 The function of two-dimensional pointer
A two-dimensional pointer as a pointer , It can also be used as a formal parameter , Make indirect access to the two-dimensional pointer in the function , To modify the arguments ( One dimensional pointer & operation ), So as to achieve the purpose of modifying one-dimensional pointer .
int g_nTest = 0x123;
// Pass out the pointer through the parameter , To pass in a second level pointer
// Pass on pn The address of is kept in ppn Parameter variables
void SetPoint(int** ppn)
{
// Indirect access occurs take pn The content of the address is modified
*ppn = &g_nTest;
}
int main(int argc, char* argv[])
{
int n = 0x888;
int* pn = &n;
// modify pn The direction of Set up pn Save the address of the global variable
SetPoint(&pn);
system("pause");
return 0;
}
Another function of a two-dimensional pointer is to receive an array of pointers , See below .
3、 ... and 、 Pointer array
It's essentially an array , Is an array of pointers . such as main In the arguments of the function :
int main(int argc, char* argv[], char* envp[])
{
// Command line to argc Parameters as end flags
for (int i = 0; i < argc; i++)
{
puts(argv[i]);
}
// Environment variables are represented by NULL As a closing sign
while (*envp != NULL)
{
puts(*envp);
envp++;
}
system("pause");
return 0;
}
A pointer array can be received with a two-dimensional pointer :
int main(int argc, char* argv[])
{
char** p = argv;
system("pause");
return 0;
}
there argv As an array name , The array name is number 0 Elements (char * type ) Pointer constants for , That is to say char** type . So receive argv You need to define a two-dimensional pointer .
Advantages and disadvantages of pointer array :
advantage : It integrates the advantages of variable length storage and fixed length storage . It has the advantage of variable length storage and variable data size , It also has the advantage of random access of fixed length storage . When sorting, you only need to exchange the pointers in the array , There is no copy of the element . The problem of finding and sorting variable length storage has been solved .
shortcoming : When the data volume is large , Insertion and deletion are expensive .
Four 、 Array pointer
4.1 Array pointer to a one-dimensional array
4.1.1 Type of array name
To illustrate , We define the following two variables , integer Variable a, Array Variable ary1.
int a = 10;
int ary1[4] = {
1,2,3,4 };
If, according to the definition of integer variables , If you want to define include 4 individual int Of type data Array ary1, The array ary1 The definition of should have been int[4] ary1;, But this kind of writing is not supported in grammar , It's written as int ary1[4];.
Although many books always say that arrays are non basic data types when talking about arrays , There is no problem with that , because int[4] Not a basic data type . But we always put the above array ary1 succeed in negotiation integer array ary1, This statement is easily misguided ary1 It's integral , But it is not , It should be said Array ary1 The member of is an integer , Or say A one-dimensional array containing integer data ary1. Although arrays are not basic types , But we put ary1 succeed in negotiation Integer array type variable ary1 Better understanding .
Java in int[4] ary1; And int ary1[4]; Both of these expressions support .C/C++ Support only int ary1[4]; This way of writing , After learning the compilation principle, we can infer that it is possible C/C++ Compiler in syntax or semantic analysis int[4] ary1; This way of writing conflicts with others .
All in all , What I want to say is to put the array ary1 It is understood as the same as ordinary variables , It's essentially a variable , The type of the variable is An array type , And is Integer array type , namely int[4]. So whether it's a one-dimensional array variable , Or two-dimensional array variables are the same .
actually , Array variables are array names , After introducing the pointer , The types of array variables need to be explained again .
For the sake of illustration , We still use one-dimensional arrays ary1.
int ary1[4] = {
1,2,3,4 };
Here we throw out the conclusion directly :
The type of array name is array number 0 Pointer constants for elements
The array name of a one-dimensional array ary1 The type of is array number 0 Pointer constants for elements , Array number 0 Elements are 1 yes int type , So it should be int Pointer constant of type , That is int* const type .
int main(int argc, char* argv[])
{
int ary1[4] = {
1,2,3,4 };
int* const p1 = ary1; // ary1 yes int* const type
return 0;
}
4.1.2 & Type of array name
Variable of a certain type & Operation to get pointers of the same type
The integer variable name takes the address to get the integer pointer , namely int Type variable & Operation result int A pointer to a type, that is int*.
int main(int argc, char* argv[])
{
int a = 10;
int* p = &a; // a by int type &a by int* type
return 0;
}
Array names are also variables , Array variable name takes address to get array pointer , One dimensional array ary1 yes int[4] type , therefore &ary1 yes int[4]* type , Because the array pointer syntax does not support this kind of writing , So it should be written as int (*)[4], This is the array pointer .
4.1.3 The value of the array name
The above is the problem of array variable types . Let's discuss the value of array variables .
For variables of basic data type , Variable has memory space size , The binary value of a variable in its memory space is the value of the variable , adopt & Variable Get the address of the variable .
For array variables , Array variables determine the size of their memory space at compile time , But the value of an array variable is different from the value of a variable , Because the array contains many elements of the same type , In fact, the value of the array variable is the address of the array in the memory space , That is, the second of the array 0 The address of the elements in the memory space , Address of the first element of the array . and & An array variable It is still the address of the array in the memory space .
All in all , Array name 、& The value of the array name is the address of the first element of the array .
4.2 Array pointer to a two-dimensional array
int nAry[2][4] = {
{
10,20,30,40},
{
60,70,80,90}
};
// It's equivalent to the following , However, the following writing methods are not supported grammatically
int[4] nAry[2] = {
// How to write it 1
{
10,20,30,40},
{
60,70,80,90}
};
int[2][4] nAry = {
// How to write it 2
{
10,20,30,40},
{
60,70,80,90}
};
From writing 2 Look at , Two dimensional array nAry The type is int[2][4].
From writing 1 Look at , Two dimensional array nAry There are two elements , Each element is a int[4] That is to say int An array of types .
If you want to receive an array name :
The array name is number 0 Pointer constants for elements . Array name nAry Of the 0 Elements nAry[0] by int[4] type , therefore nAry yes int[4]* type . So you can define variables like this int[4] *p = nAry;, Also, the syntax does not support , The correct way to write it should be int (*p)[4] = nAry;.
If you want to receive & Array name :
Variable of a certain type & Operation to get pointers of the same type . An array is int[2][4] type , therefore &nAry yes int[2][4]* type , This kind of writing is not supported in grammar , Should be written as int (*p)[2][4] = &nAry.
4.3 This section summarizes
int main(int argc, char* argv[])
{
int ary1[4] = {
1,2,3,4 };
int *p1 = ary1;
int(*p2)[4] = &ary1;
int nAry[2][4] = {
{
10,20,30,40},
{
60,70,80,90}
};
int(*p3)[4] = nAry;
int (*p4)[2][4] = &nAry;
return 0;
}
5、 ... and 、 A function pointer
The function pointer stores the address of the function . The name of the function is the address of the function ,& The value of the function name is also the address of the function .
void test(int n)
{
printf("test:%d\r\n", n);
}
int main(int argc, char* argv[])
{
// Function name = & Function name = Function address
printf("%p\r\n", test);
printf("%p\r\n", &test);
return 0;
}
5.1 Function pointer definition and call
void test(int n)
{
printf("test:%d\r\n", n);
}
int main(int argc, char* argv[])
{
// Define function pointer variables pfun
void (*pfun)(int n);
// Function pointer variable assignment
pfun = test;
pfun = &test;
// Call the function saved by the function pointer
pfun(1);
(*pfun)(100);
return 0;
}
The defined function pointer variable should have been written in this way void(*)(int n) pfun;, With a return value 、 Pointer to parameter , It's just that the grammar doesn't support this kind of writing .
But you can use typedef Rewrite the above definition ,typedef You can define a function pointer as a type .
typedef void(*PFUN)(int n);
int main(int argc, char* argv[])
{
PFUN pfun = test;
(*pfun)(100);
return 0;
}
typedef Is equivalent to void(*)(int n) Name it PFUN.
Look at the code below :
(*(void(*)())0)();
The meaning of this code is , call 0 The code at the address . First of all, will 0 Convert to function function pointer void(*)() No parameter, no return value type , And then call the function. . The code is essentially a function call .
It is worth mentioning that there are two ways to call function pointers , Recommended (*pfun)(); This way of calling , Another way pfun() In some cases it may not be possible to use , As called above 0 The code at the address .
5.2 A function whose return value is a function pointer
Look at the code below :
void (*signal(int, void(*)(int n)))(int n);
The meaning of this code is to define a return value that is void(*)(int n) type , One of the parameters is int type , For another void(*)(int n) Function of type . It is essentially a function definition .
Since the above code is essentially a function definition , So how to write a function pointer to this function ?
void (*(*signal)(int, void(*)(int n)))(int n);
For the function pointer defined above , First (*signal) Is a function pointer ,void(*)(int n), Is the return value of the function and also a function pointer , The argument to this function is (int, void(*)(int n)).
Use typedef The code can be rewritten as :
typedef void(*PFUN)(int n);
int main(int argc, char* argv[])
{
//void (*signal(int, void(*)(int n)))(int n);
PFUN signal(int, PFUN);
return 0;
}
It also shows that , When defining a function whose return value is a function pointer , In writing , You need to write the function parameters immediately after the function name , As above
(int, void(*)(int n)). The return value of the function is just outside the parentheses that enclose the function name and parameters – A function pointer .
5.3 Function pointer array
Arrays hold the same type of data , When the data type is a function pointer , It becomes an array of function pointers , The definition is as follows :
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int main(int argc, char* argv[])
{
int (*pfun[2])(int a, int b);
pfun[0] = add;
pfun[1] = sub;
return 0;
}
Use typedef To rewrite :
typedef int(*PFUN)(int a, int b);
int main(int argc, char* argv[])
{
PFUN pfun[2] = {
add, sub };
return 0;
}
Two ways to call functions :
int sum1 = pfun[0](1, 2);
int sum2 = (*pfun[0])(1, 2);
5.4 Array pointer of function pointer array
int (*pfun[2])(int a, int b);
typedef int(*PFUN)(int a, int b);
PFUN pfun[2] = {
add, sub };
For function pointer arrays , The type of array name is array number 0 Pointer constants for elements , The... In the function pointer array 0 The types of the elements are PFUN, namely int(*)(int a, int b). Analogy of one-dimensional array and its function pointer , Arrays can be received with pointers , So there is the following code :
int main(int argc, char* argv[])
{
PFUN pfun[2] = {
add, sub };
PFUN* pPfun = pfun;
return 0;
}
Here is another way to write :
int main(int argc, char* argv[])
{
int(*pfun[2])(int a, int b);
int(**pPfun)(int a, int b) = pfun;
return 0;
}
First, the element type in the function pointer array is int(*)(int a, int b), Its pointer type is int(**)(int a, int b)
about & Function pointer array , Variable of a certain type & Operation to get pointers of the same type , The type of function pointer array is PFUN[2], That is to say int(*[2])(int a, int b);
int main(int argc, char* argv[])
{
PFUN pfun[2] = {
add, sub };
PFUN(*ppp2)[2] = &pfun;
return 0;
}
Another way of writing :
int main(int argc, char* argv[])
{
int(*pfun[2])(int a, int b);
int(*(*pPfun)[2])(int a, int b) = &pfun;
return 0;
}
First int(*[2])(int a, int b) Is the type of function pointer array , Its pointer int(*(*pPfun)[2])(int a, int b).
6、 ... and 、 summary
*(arr + n) = arr[n]
The type of array name is array number 0 Pointer constants for elements
Variable of a certain type & Operation to get pointers of the same type
7、 ... and 、 practice
边栏推荐
- [big guy show] aiops in the eyes of Borui data, choosing the right track and the right people
- Helm deploy traifik ingress
- Looking at the ups and downs of the mobile phone accessories market from the green Union's sprint for IPO
- intXX_ T and int_ fastXX_ T what is the difference- What is the difference between intXX_ t and int_ fastXX_ t?
- The two departments jointly issued the nine provisions on fire safety management of off campus training institutions
- postgresql源码学习(十八)—— MVCC③-创建(获取)快照
- What is the difference between a database unique index and a common index?
- Go语言之Go 快速入门篇(一):第一个 Go 程序
- The solution of invalid @data annotation in idea2018
- 最长递增子序列
猜你喜欢

Necessity for banks to choose electronic bidding procurement

Cygwin reports an error child_ info_ fork::abort: XXX. dll: Loaded to different address: parent(XXX) != child(XXX)

org. apache. solr. common. SolrException:Could not load core configuration for core hotel

Operations on annotation and reflection

Solr import MySQL database report: Data config problem: invalid byte 2 of 2-byte UTF-8 sequence

Application of the remote acquisition IOT gateway of the Bashir trough flowmeter in open channel flow monitoring

WinDbg-虚拟机-双机调试-驱动文件的调试

RS232/RS485转4G DTU 上传基于Modbus协议的温湿度传感器数据到远程TCP服务器
![[long time series prediction] aotoformer code detailed [3] model overall architecture analysis](/img/77/30215c363ae8a1324db1cbcaa5324b.png)
[long time series prediction] aotoformer code detailed [3] model overall architecture analysis

Visit the swagger times unable to infer base url
随机推荐
Android P SoftAP start process
UBIFS FAQ and HOWTO
Deep parsing of question mark expressions
Visit the swagger times unable to infer base url
HUST软件工程(实验2)--TDD测试驱动开发实验。
两部门联合印发《校外培训机构消防安全管理九项规定》
关于玩家身上有个普通Set并发安全的讨论
Help you distinguish GNU, GCC, GCC and G++
OpenJudge NOI 1.13 17:文字排版
Blue Bridge Cup_ Xiao Lan eats candy_ Pigeon nest principle / drawer principle
C语言指针
Win10 安装Office 2016出现错误代码30204-44怎么处理?
js 内存泄漏
出栈序列是否是入栈序列
Cygwin reports an error child_ info_ fork::abort: XXX. dll: Loaded to different address: parent(XXX) != child(XXX)
微信模版消息errcode“:40165,“errmsg“:“invalid weapp pagepath
Hqchart actual combat tutorial 55 area map of K line of ouyi.com
RS232/RS485转4G DTU 上传基于Modbus协议的温湿度传感器数据到远程TCP服务器
Problems with JDBC tool classes
深入解析问号表达式