
Due to changes in the public account’s push rules, please click “View” and add “Star Mark” to get exciting technical shares immediately
Source from the internet, please delete if infringing
1 Basic Operations of Pointer Variables
int a,*iptr,*jptr,*kptr;
iptr = &a;
jptr = iptr;
*jptr = 100;
kptr = NULL;
Illustration:
1.1 Self Address and Self Space
Pointer variables are also variables, corresponding to a block of memory space, corresponding to a memory address, and the pointer name is the self address. How big is this empty memory space? One machine word (machine word), 32-bit CPU and operating system means 32 bits, 4 bytes, with a value range of: 0x-0xFFFFFFFF. A 64-bit CPU and operating system means 64 bits, 8 bytes, with a value range of: 0x-0xFFFFFFFFFFFFFFFF.
1.2 Self Value, Other Address, Other Space
The value of a pointer variable is the address of the space it points to, and the size of the space at that address is the size of the type that the pointer variable points to.
1.3 Declaration and Initialization
When declaring a pointer variable without initialization, the pointer variable only obtains its own memory space, and its pointing has not yet been determined. At this time, dereferencing the pointer variable as a left value is an illegal operation. If you want to dereference the pointer variable as a left value, there are three ways:
int *ptr;
int *ptr_2;
int a = 1;
ptr_2 = &a;
// *ptr = 0; // Illegal operation, its pointing has not been determined
ptr = &a; // ① Right value is a variable address
ptr = ptr_2; // ② Right value is a same type pointer, and has been initialized
ptr = (int*)malloc(sizeof(int));// ③ Right value is a memory allocation function returning a void pointer
*ptr = 0; // Legal operation, ptr has a definite pointing and pointing memory space;
1.4 Passing Pointer Values Between Functions
Functions (like the example funcForSpace()) define local variables (like the example a) saved on a function’s stack frame. When one function finishes executing, another function (like the example stackFrame_reuse()) executes, and that space will be reused by stackFrame_reuse(), so the space used by a will no longer exist. Therefore, when a pointer variable points to the memory space of a local variable, its address value passed to the calling function is not a valid value.
#include <stdio.h>
void funcForSpace(int **iptr) {
int a = 10;
*iptr = &a;
}
void stackFrame_reuse()
{
int a[1024] = {0};
}
int main()
{
int *pNew;
funcForSpace(&pNew);
printf("%d\n",*pNew); // 10, at this time the stack frame has not been reused
stackFrame_reuse();
printf("%d\n",*pNew); // -858993460, garbage value
while(1);
return 0;
}
You can allocate a block of heap memory in funcForSpace() and pass it to the calling function.
#include <stdio.h>
#include <malloc.h>
int g(int **iptr) { // When trying to modify the first-level pointer variable of the calling function, the parameter of the called function is a second-level pointer
if ((*iptr = (int *)malloc(sizeof(int))) == NULL)
return -1;
}
int main()
{
int *jptr;
g(&jptr);
*jptr = 10;
printf("%d\n",*jptr); // 10
free(jptr);
while(1);
return 0;
}
We can illustrate the pointer passing process of the above code:
The following illustration shows that a represents computer memory, and b represents the stack frame space opened during a function call:
2 Pointer Variables and Array Names
In certain contexts, the array name will convert to the address of the first element of the array to facilitate pointer arithmetic, such as
#include <stdio.h>
int main()
{
int a[5] = {0};
char b[20] = {0};
*(a+3) = 10; // a+3 is relative to address a, offset by sizeof(int) bytes
*(b+3) = 'x'; // b+3 is relative to address b, offset by sizeof(char) bytes
printf("%d, %c\n",a[3],b[3]); // 10, x
while(1);
return 0;
}
We can illustrate the pointer offset details of the above code:
3 Pointer Passing Between Calling and Called Functions
Look at the following code:
#include <stdio.h>
void swap1(int x, int y) {
int tmp;
tmp = x; x = y; y = tmp;
}
void swap2(int *x, int *y) {
int tmp;
tmp = *x; *x = *y; *y = tmp;
}
void caller()
{
int a = 10;
int b = 20;
swap1(a,b);
printf("%d %d\n",a,b);
swap2(&a,&b);
printf("%d %d\n",a,b);
}
int main()
{
caller();
return 0;
}
The above code can be understood with the following illustrations:
swap1 by value:
swap2 by address (pointer passing):
4 Arrays as Function Parameters
Multi-dimensional arrays are arrays of arrays, and n-dimensional arrays are arrays of (n-1)-dimensional arrays. Memory is a one-dimensional byte sequence; the so-called n-dimensional array is merely a logical representation, while its physical structure is still one-dimensional linear.
The elements of an n-dimensional array are an (n-1)-dimensional array. If you point to an n-dimensional array with a pointer, the pointer type must have (n-1)-dimensional length information, and this is also true when used as a function parameter.
void g(int a[][2]) { // void g(int(*a)[2]){ is the same writing
a[2][0] = 5;
}
void caller()
{
int a[3][2];
int (*p)[2] = a;
*(*(p+2)+0) = 7; // p=2 means offset by sizeof(*p) relative to address p
printf("%d\n",a[2][0]); // 7
g(a);
printf("%d\n",a[2][0]); // 5
}
The following code can be assisted by the following illustration:
ref:Kyle Loudon《 Mastering Algorithms with C》
If you are over 18 years old and find learning 【C language】 too difficult? Want to try other programming languages, then I recommend you learn Python. Currently, a Python zero-based course worth 499 yuan is available for free for a limited time, with only 10 spots!
▲ Scan the QR code - Get it for free
