Summary
1) The essence pointer is a variable. The special feature is that
pointer is the memory address (the number of each storage unit in the
: the smallest storage unit in the computer is 1 byte, that is, the number of each byte is A memory address)
2) All elements in the program exist in memory, so program elements can be accessed through memory addresses
3) The essence memory address is an unsigned integer (4 bytes or 8 bytes); 4 bytes and 8 bytes correspond to 32 bits and 64 bits, respectively, so the 32-bit and 64-bit systems we often refer to
is the maximum memory address that can be accessed by 1610667c63c248. Because 64-bit systems can support greater memory addressing, 64-bit systems can run more programs simultaneously than 32-bit systems.
4) Only through memory address + length can the value saved in a variable be determined. The memory address is just a starting value. Only when the
type information is used to know how much memory it occupies and how to read it, can the value stored in the variable be accurately read.
5) When the function parameter is a pointer ( call by address), the value of the external variable of the function can be modified within the function; using a pointer as a parameter can be used as a
outgoing parameter, so that the function can return multiple values.
6) For the array int a[5], a and &a:
- a can be regarded as
, representing the address of the first element of the array, the value is 0xA, the type is int*, that is, the memory length is 4
- &a is the address of the array, the value is 0xA, and the type is int(*)[5], that is, the memory length is 20. Pointer to the array:
int(*pArr)[5] = &a;
7) The equivalent usage of pointers and arrays:
int a = {1, 2, 3, 4, 5};
int* p = a;
a[i] <--> *(a + i)
<--> *(p + i) <--> p[i]
8) In C language, the type of string constant is char*
(const char* in C++); int v = *p++; equivalent to int v = *p; p++; because (*) has the same priority as (++)
9) The function is essentially a piece of code in memory, and
occupies a piece of continuous memory. The function name is the
entry address of the function (the starting address of the function body code). By
caller of the function name,
nature to specify a specific address jump execution. Therefore, you can define a pointer to save the entry address of the function: type (*pFunc)(param) = funcName;
10) Q: Since functions can be directly called by function names, why do we need function pointers?
Answer: You can define function pointer parameters.
uses the same code to achieve different functions. The calling function only knows that the function prototype is like this, but it doesn't know which function will be called.
function pointer is the implementation mechanism of the
callback function: when the function is used as a parameter, it constitutes a callback;
11) The essence of the heap space is the spare "memory warehouse" , the available memory reserved in the unit of
12) In the C language, the void*
pointer and other types of pointers type*
can perform mutual assignment, because the C language does not strictly check the pointer. However, you must pay attention to the data type of the operation when using it. void* is only an initial address and does not contain the length information of
.
13) malloc is used to apply for memory in the heap space in bytes; free is used to return the memory in the heap space, malloc is not free, memory leaks; multiple frees, crashes.
14) The pointer is a variable, so naturally there will be pointers to pointers, that is, multi-level pointers. Before variables can use pointers to call by address, then you can also use multi-level pointers to call pointers by address, changing the value of the external pointer inside the function.
two-dimensional array is essentially a one-dimensional array, so the two-dimensional array name a represents the first element of the array, that is, a[0] represents a one-dimensional array; the type of a is type (*)[size2 ]
int arr[2] = {0};
int* pa = arr;
int (*pArr)[2] = &arr;
int bArr[2][2] = {0};
int (*pb)[2] = bArr;
typedef int (oneDimension)[2];
oneDimension (*pbArr)[2] = &bArr;
16) forbidden to return the address of a local variable, because the life of a local variable ends after the function call ends. What is returned at this time is a
wild pointer.
1. Pointer
1.1 The nature of pointers
The pointer is essentially
variable in the C language
- Because it is a variable,
used to save the specific value
, the value saved by the pointer 1610667c63c5b7 is the address in the memory
What is a memory address?
- Memory is a storage component in a computer, and each storage unit has a fixed and unique number (each storage unit: 1 byte)
- The number of the
storage unit in the memory is the memory address
All elements in the program exist in memory, so program elements can be accessed through memory addresses.
Get address:
- Get the address of the program element through the & operator in C language
- & Get the starting address of variables, functions, and arrays
memory address is essentially an unsigned integer (4 or 8 bytes)
int var = 0; printf("var address = %p\n", &var);
1.2 Pointer syntax
Pointer definition syntax: type * pointer
- type-data type,
determines the length range when accessing memory
*
-flag, which means to define a pointer variable- pointer-variable name, follow C language naming rules
Pointer memory access: * pointer
- The pointer access operator (*) acts on the pointer variable to access memory data
- The type of pointer determines the length range when accessing memory through the address
- The pointer type uniformly occupies 4 bytes or 8 bytes
Military rules when you first learn the pointer:
- A pointer of type
type*
type
(such as float and int type variables, both are 4 bytes, but the binary in the memory is different. If the stored int is int, it can be read as a float , It must be wrong) prohibits the assignment of pointers of different types to each other
forbidden to assign ordinary values to pointers as addresses
- Note: The address saved by the pointer must be a valid address
Question: Is it really impossible to exchange the values of two variables in a function before?
Thinking: If you want to exchange the values of two variables, you must modify the variables outside the function number inside the function? What if the parameter is a pointer? Is it feasible to pass in the address of the variable and directly modify the address through the memory address in the function?
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
By passing pointers, the variables outside the function can be modified inside the function. In addition, the return of the function can only return one value. If a pointer is used in the parameter, the function can return multiple values. passes the parameter.
2. Pointers and arrays
Question: The essence of an array is a piece of contiguous memory. So, what is the address of the array? How to get it?
2.1 Pointers and ordinary arrays
- Use the address character & to get the address of the array: &a, &a represents an address (the address of the array), the value is 0xA, the type is
int(*)[5]
, that is, the length is 20. Pointer to array: int(*pName)[5] = &a; - The array name can be seen as a constant pointer: a, a represents an address (the address of the first element of the array), the value is 0xA, the type is
int*
, that is, the length is 4. When the pointer points to an array element, pointer arithmetic (pointer movement) can be performed
int a[] = {1, 2, 3, 4, 5}; int* p = a; p = p + 1;
Note: The array name can only be regarded as a pointer, representing the address of element 0.
The equivalent usage of pointers and arrays:
int a = {1, 2, 3, 4, 5};
int* p = a;
a[i] <--> *(a + i)
<--> *(p + i) <--> p[i]
2.2 Pointers and strings
String Supplements
- Question: What is the type of string constant in C language?
Answer:
char*
type, a pointer typeprintf("%p\n", "GrandSoft");
Pointer movement combination punch: int v = *p++;
- The pointer access operator (*) and the increment operator (++) have the same precedence
- So, first get the value from the memory pointed to by p, and then move p
- Equivalent to: int v = *p; p++;
3. Pointers and functions
Question: When a function is called, it will jump to the code corresponding to the function body for execution. Then, how do you know the specific location of the function body code?
In-depth function tour:
function is essentially a piece of code in memory (occupies a piece of continuous memory)
Function has a type,
function type is composed of return type and parameter type list
Function declaration Types of int sum(int n) int(int) void g(void) void(void)
Function pointer: type func(type1 a, type2 b)
- The function name is the function entry address, and the type is
type (*)(type1, type2)
- For func functions, func and &func
same value, and
has the same meaning
Pointer to function: type (*pFunc)(type1, type2) = func;
int (*pFunc)(int a, int b) = nullptr; pFunc = add; printf("%d\n", pFunc(1, 2)); // 1) printf("%d\n", (*pFunc)(1, 2)); // 2)
Understanding of the two calling methods:
1) The function pointer saves the entry address of the function, and the function name also saves the entry address of the function. The function name can directly call the function, so it is reasonable to use pFunc to directly call the function.
2) pFunc is an address, the code of the function stored in it, the function body is obtained by using *pFunc, and it is reasonable to call the function directly.
Question: Since a function can be called directly by its name, why do we need to use a function pointer?
Answer: In this way, you can use the function pointer as a function parameter.
- The essence of function pointer is pointer (variable, save address)
Function pointer parameters can be defined,
uses the same code to achieve different functions
int calculate(int a[], int len, int(*cal)(int, int)) { int ret = a[0]; int i = 0; for(i=1; i<len; i++) { ret = cal(ret, a[i]); } return ret; }
According to the different cal functions that are passed in, it is possible to realize, for example, array multiplication, addition, division and so on. In calculate,
only knows the prototype of the function to be called, but
specifically calls and what function is executed,
only knows when cal is executed.
4. Pointers and heap space
Discuss the memory space again: different memory areas have different uses
- Global data area: store global variables, static variables
- Stack space: store function parameters, local variables
- Heap space: used to dynamically create variables (arrays)
The nature of heap space:
spare "memory warehouse", available memory reserved in bytes
- The program can apply for the use of memory from the "warehouse" when needed (
dynamically borrowed)
- When the requested memory is no longer needed, it needs to be returned in time (
dynamic return)
Preliminary knowledge-void*
- The void type is the basic type, and the corresponding pointer type is void*
- void* is a pointer type, its pointer variable can save the address
- The data in the memory cannot be obtained through the void* pointer
(no length information)
Use of heap space:
- Toolkit: stdlib.h
- Application: void* malloc(unsigned bytes)
- Return: void free(void* p), p must be an address in the heap space
Principles for the use of heap space:
- It’s not difficult to pick up
- After malloc applies for memory, it should be
determine whether the application is successful
- free can only apply for the released memory, and
cannot be released multiple times
5. Analysis of the pointer problem
5.1 Multi-level pointers
You can define the pointer of the pointer to save the address of other pointer variables
type v;
type* pv = &v;
type** ppv = &pv;
type*** ppv = &ppv;
...
You can get the address of the pointer by using the pointer, then you can change the value stored in the pointer inside the function.
Call by pointer to modify the value of the pointer outside the function:
int getDouble(double** pp, unsigned int n)
{
int ret = 0;
double* pd = (double*)malloc(sizeof(double) * n);
if(pd != NULL)
{
*pp = pd;
ret = 1;
}
return ret;
}
5.2 Two-dimensional array
Question: The type of the one-dimensional array name is type , so is the type of the two-dimensional array name type *?
Discuss the two-dimensional array again:
- The essence of a two-dimensional array is a one-dimensional array, that is: the elements in the array are a one-dimensional array
Therefore: a two-dimensional array a[][], a represents a[0], the first element is a one-dimensional array
int b[][2] = {1, 2, 3, 4}; int(*pnb)[2] = b;
This article is summarized from "Introduction to C Language Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。