Next, the pointer array stores the pointer char *arr[5]; Array pointer is a pointer to an array
int arr[5];
//arr is an integer array. Each element is of type int and has five elements
int* parr1[10];
//parr1 is an array with 10 elements, and the type of each element is int*
int(*parr2)[10];
//parr2 is a pointer to an array. The array pointed to has ten elements, and the type of each element is int*
int(*parr3[10])[5];
//parr3 is first combined with []. parr3 is an array with ten elements. The type of each element is int(*)[5],
//parr3 is an array that holds array pointers
4. Array parameters and pointer parameters
When writing code, it is inevitable to pass [array] or [pointer] to the function. How to design the parameters of the function?
4.1 one dimensional array parameters are written in array form
void test(int arr[10]) / / or the array size of the parameter part of void test(int arr []) can be omitted
The shape parameter group here is ten meaningless array names. When passing parameters, it is essentially the address of the first element of the array passed. The formal parameters do not need to be created
To accept an array, as long as you know the first address, you can traverse the contents behind the array
Formal parameters are written as pointers
void test(int *p) { } void test2(int* arr[])//Or void test2(int *arr[20]) numbers can be written at will, which essentially does not create an array { } void test2(int** p) { } int main() { int arr[10] = { 0 }; int* arr2[10] = { 0 }; test1(arr);//The array name represents the address of the first element test2(arr2); return 0; }
4.2 two dimensional array parameter transfer
int main()
{
int arr[3][5] = { 0 };
test(arr);
return 0;
}
Write out the form of array with formal parameters
void test(int arr[3][5])//ok
{}
void test(int arr[][])//err
{}
void test(int arr[][5])//ok
{}
//Summary: for two-dimensional array parameters, the design of function parameters can only omit the first [] number.
//Because for a two-dimensional array, you can't know how many rows there are, but you must know how many elements there are in a row.
//This is convenient for calculation
Formal parameters are written in the form of pointers
The address of the first element passed is the address of the first row for a two-dimensional array
void test(int (*p)[5])
p+1 means coming to the second line, and p+2 means coming to the third line
4.3 primary pointer transfer parameter
void print(int* p, int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d\n", *(p + i)); //ptr++//ptr + + is the address in ptr + +; As an integer pointer + 1, it skips four bytes to access the next element } } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9 }; int* p = arr; int sz = sizeof(arr) / sizeof(arr[0]); //First level pointer p, passed to function print(p, sz); return 0; }
4.4 secondary pointer transfer parameter
void test(char** ppc) / / secondary pointer reception
{
}
int main()
{
char a = 'w';
char* pa = &a;
char** ppa = &pa;
test(ppa);// Secondary pointer transfer
return 0;
}
What we need to think about is: what parameters can we receive when the parameter of the function is a secondary pointer?
void test(char** ppc)
{
}
int main()
{
char ch = 'w';
char* pa = &ch;
test(&pa);// First level pointer fetching address
char** ppa = &pa;
test(ppa);// Direct transmission of secondary pointer
char* arr[5];
test(arr);// When transmitting an array, you can directly transmit the pointer array, char * type, and its address is char * * type
return 0;
}
A two-dimensional array cannot be passed in
char arr [3][5];
test(arr) / / the array name represents the address of the first element. For the secondary pointer, it is the first line. The type of each element is char(*p)[5]
void test01(int (*p)[5])
{}
void test02(int (*p)[3][5])
{}
int main()
{
int arr[3][5];
test1(arr);// The address of the line is passed
test2(&arr);// Passing is the address of the entire two-dimensional array -- not common
return 0;
}
When passing a two-dimensional array, the past dereference of the two-dimensional array represents the address of the first line
5. Function pointer
Array pointers are pointers to arrays and natural function pointers are pointers to functions
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 ", &add); printf("%p ", add); //Although the writing method is different, but the meaning is the same. They all represent the address of the function. Unlike an array, it has the address of the first element and the address of the array. int (*pf)(int, int) = add;//pf here is the function pointer variable //pf is first combined with * to prove that it is a pointer, and then there are two int parameters pointing to add. Removing pf is the function pointer type int ret=(*pf)(2, 3);//The * here is optional, no matter how many * you write. However, some * conform to the grammatical rules //You must add () after * or de reference the result of the function printf("%d\n", ret); //The function can be found through the pointer, and add(2,3) can also be called normally //As can be seen from the function pointer, add is assigned to pf, which is also add int ret1 = pf(2, 3); printf("%d\n", ret1); return 0; }
int main() { //void (*) () is a function pointer type //(void (*p)() type in parentheses means forced type conversion //Here is the forced type conversion of 0 to function pointer. We think that such a function is placed at the address of 0 1.(*( void (*)() ) 0 )(); //1. The meaning of this code is to first convert the 0 mandatory type to a function pointer type, which means that one is placed at the 0 address //A function whose return type is void and has no parameters //2. Call this function at address 0 2.void (*signal(int, void(*)(int)))(int);//Function declaration //This function can also be simplified // typedef void (*pf_t)(int); Rename the function pointer type void (*) (int): PF_ t; // So the above function is simplified as: // pf_t singal(int,pf_t); //signal is the declaration of a function //The first parameter of signal function is int type, and the second is void (*) (int) function pointer type //The return value type of the signal function is also a function pointer of void (*) (int) return 0; }
6. 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]; //Integer pointer array int* arr1[5]; //Function pointer array int(*pf1)(int, int) = add; int(*pf2)(int, int) = sub; int(*pf3)(int, int) = mul; int(*pf4)(int, int) = div; //Array of function pointers. The array is combined with [] 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 ", ret); } return 0; }
Purpose of function pointer array: transfer table
Instantiate a calculator
int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } int main() { int x, y; int input = 1; int ret = 0; do { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf("*************************\n"); printf("Please select:"); scanf("%d", &input); switch (input) { case 1: printf("Input operand:"); scanf("%d %d", &x, &y); ret = add(x, y); printf("ret = %d\n", ret); break; case 2: printf("Input operand:"); scanf("%d %d", &x, &y); ret = sub(x, y); printf("ret = %d\n", ret); break; case 3: printf("Input operand:"); scanf("%d %d", &x, &y); ret = mul(x, y); printf("ret = %d\n", ret); break; case 4: printf("Input operand:"); scanf("%d %d", &x, &y); ret = div(x, y); printf("ret = %d\n", ret); break; case 0: printf("Exit program\n"); break; default: printf("Selection error\n"); break; } } while (input); return 0; }
The code here is redundant.
Use function pointers to optimize our code
#include <stdio.h> int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } int main() { int x, y; int input = 1; int ret = 0; int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //Transfer table while (input) { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf("*************************\n"); printf("Please select:"); scanf("%d", &input); if ((input <= 4 && input >= 1)) { printf("Input operand:"); scanf("%d %d", &x, &y); ret = (*p[input])(x, y); } else printf("Incorrect input\n"); printf("ret = %d\n", ret); } return 0; }
7. Pointer to function pointer array
int add(int x, int y) { return x + y; } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int(*p)[10] = &arr;//Array pointer int* arr2[10]; int(*p1)[10] = &arr2; //Function pointer int (*pf)(int, int) = &add; //Function pointer array int (*pfarr[5])(int, int);//Pointer to store function int(*(*p3)[5])(int ,int)=&pfarr;//p3 is a pointer to an array of function pointers return 0; } //*p3==pfarr //(*p3)[i]==pfarr[i]
8. Callback function
A callback function is a function called through a function pointer. If you pass the pointer (address) of a function as a parameter to another function, when the pointer is used to call the function it points to, we say it is a callback function. The callback function is not directly called by the implementer of the function, but by the other party when a specific event or condition occurs. It is used to respond to the event or condition. In short, there are two functions AB, which pass the address of a as a parameter to function B. There are parameters in function B to receive it. Accessing function a through a pointer in function B is called a callback function.
Using function callback can optimize our code, take the calculator example above for example
int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int div(int a, int b) { return a / b; } void cal(int (*p)(int, int)) { int x = 0; int y = 0; printf("Please enter two operands\n"); scanf("%d %d", &x, &y); int ret = p(x, y); printf("%d\n", ret); } int main() { int x, y; int input = 1; int ret = 0; do { printf("*************************\n"); printf(" 1:add 2:sub \n"); printf(" 3:mul 4:div \n"); printf("*************************\n"); printf("Please select:"); scanf("%d", &input); switch (input) { case 1: cal(&add); break; case 2: cal(&sub); printf("ret = %d\n", ret); break; case 3: cal(&mul); break; case 4: cal(&div); break; case 0: printf("Exit program\n"); break; default: printf("Selection error\n"); break; } } while (input); return 0; }
//qsort is a library function
//A sort function based on quick sort algorithm
//Any type of data can be arranged
//Bubble sorting is also a sort, but it can't be used to sort all types of data. Simply review it, it doesn't have generality
void bubble_sort(int arr[], int sz) { int i = 0; for (i = 0; i < sz - 1; i++)//Number of trips { int j = 0; for (j = 0; j < sz - i - 1; j++)//Logarithm of a pairwise sort { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } int main() { int arr[10] = { 2,1,3,5,6,4,7,8,9,10 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); return 0; }
Here we know that the header file of qsort is stdlib h
#include<stdlib.h> #include<string.h> void bubble_sort(int arr[], int sz) { int i = 0; for (i = 0; i < sz - 1; i++)//Number of trips { int j = 0; for (j = 0; j < sz - i - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } void test1() { int arr[10]= { 2,1,3,5,6,4,7,8,9,10 }; //Sort in ascending order int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); } int cmp_int(const void* e1, const void* e2) { //* e1 and * e2 cannot be directly compared here //Both e1 and e2 are void * pointers. They are inexact pointers and cannot be dereferenced directly. They are used to receive any type. //Can be cast to the type you need /*if (*(int*)e1 > *(int*)e2) { return 1; } else if (*(int*)e1 == *(int*)e2) { return 0; } else { return -1; }*/ //The return type here is too troublesome. The following optimization can be used return (*(int*)e1 - *(int*)e2); } void print_arr(int arr[], int sz) { for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } } void test2() { int arr[10] = { 2,1,3,5,6,4,7,8,9,10 }; //Sort in ascending order int sz = sizeof(arr) / sizeof(arr[0]); //The comparison function requires the user of qsort function to customize a comparison function //Sorted integer data: use >< //Sorted structure data: it may be inconvenient to use directly > < compare //According to the actual situation, the user provides a function to compare the two data qsort(arr, sz, sizeof(arr[0]), cmp_int); print_arr(arr, sz); } //Sorting structs using qsotr struct stu { char name[20]; int age; double score; }; int com_stu_by_age(const void *e1,const void *e2)//Ranked by age { return ((struct stu*)e1)->age - ((struct stu*)e2)->age; } int com_stu_by_name(const void* e1, const void* e2)//When comparing names, strings cannot be subtracted. Use strcmp { return strcmp(((struct stu*)e1)->age , ((struct stu*)e2)->age); } void test3() { struct stu arr[3] = { {"Zhang San",20,55.5},{"Li Si",30,88.0},{"Wang Wu",50,90.0}}; int sz1 = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz1, sizeof(arr[0]), com_stu_by_age); qsort(arr, sz1, sizeof(arr[0]), com_stu_by_name); } int main() { //test2(); test3(); return 0; } //e1-e2 for ascending order and e2-e1 for descending order;
The strcmp library function is also specified
abcdef compared with abq; All the above are the same. If the ASCII value of c must be less than q, it returns < 0
The cmp function designed in qsort returns a number greater than 0 if the object pointed to by the incoming parameter e1 is larger than e2
The picture is normal
If E1 < E2 returns a number greater than 0, the logic is the opposite
If it is the same as the logic in the library function, it is in ascending order
On the contrary, it is in descending order.
After understanding qsort, we can transform our bubble sorting into more than just integer data.
int cmp_int(const void* e1, const void* e2) { return (*(int*)e1 - *(int*)e2); } //1 and 2 are stored in memory (small end) 01 00 00 00 02 00 00 00 00 00 00 //buf1 points to 01, buf2 points to 02, char * can only operate one byte at a time, first exchange 01 and 02, and the other 00 and 00 can be exchanged later 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++)//Number of trips { int j = 0; for (j = 0; j < num - i - 1; j++) { //if (arr[j] > arr[j + 1]) if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0) //Here, how to use cmp function to express the effect of array size comparison before //Let's take arrays as an example //int arr[5]={1,2,3,4,5); //To compare 1 and 2, the function parameter only provides us with void *base //How to find out 1 and 2? base is a void * pointer, and char * is used to convert it into a char * pointer //It takes four bytes, (char*)base+width. If integer, the width is 4 //A char * pointer plus 1 adds a byte, plus 4 adds four bytes, and you can find 2 //Give width*j to find the address of the element you want to find { //exchange swap((char*)base + j * width, (char*)base + (j + 1) * width,width); } } } } void print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } void test4() { int arr[] = { 9,8,7,6,5,4,3,2,1 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_int); print_arr(arr, sz); } int main() { test4(); return 0; }
At this time, our bubble can discharge any type of data. Including previous structures
Here are some different forms of applications
//What is the array name? //The array name is usually the address of the first element of the array //But there are two exceptions //1. Sizeof (array name), where the array name represents the whole array, and the size of the whole array is calculated //2. & array name, where the array name represents the whole array, and the address of the whole array is taken out int main() { int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//4*4=16 printf("%d\n", sizeof(a + 0));//This is not a separate array name. It represents the address of the first element. The address of integer + 0, / / 4 / 8 (64 bits) printf("%d\n", sizeof(*a));//A represents the address of the first element, * a represents the first element of the array, sizeof (* a) is the size of the first element, 4 printf("%d\n", sizeof(a + 1));//A represents the address of the first element of the array. The address of the second element of the a+1 array. sizeof (a+1) is the size of the address of the second element, 4 / 8 printf("%d\n", sizeof(a[1]));//Second element of the array, 4 printf("%d\n", sizeof(&a));//This is the address of the array, but the address of the array is also the address. The size is four or eight bytes. printf("%d\n", sizeof(*&a));//&A takes the entire array, * a gets the entire array, that is, the size of the entire array, 16, which is equivalent to offsetting sizeof(a) printf("%d\n", sizeof(&a + 1));//&A is the address of the array, and + 1 skips the entire array to generate the address after 4, but it is still the address, that is, 4 / 8 bytes printf("%d\n", sizeof(&a[0]));//Take the address of the first element of the array, 4 / 8 printf("%d\n", sizeof(&a[0] + 1));//Take the address of the second element of the array 4 / 8 return 0; }
#include<string.h> int main() { //Character array char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr));//6byte. If it is strlen, there is no \ 0 here, and a random value will appear printf("%d\n", sizeof(arr + 0));//4 / 8, address of the first element of arr+0 array printf("%d\n", sizeof(*arr));//*arr is the first element, and the size is one byte printf("%d\n", sizeof(arr[1]));//arr[2] is the second element of the array, with a size of one byte printf("%d\n", sizeof(&arr));//4 / 8 & arr is the address of the array and is placed in the char (* p) [6] array pointer printf("%d\n", sizeof(&arr + 1));//&Arr + 1 is an address generated by skipping the whole array back from the array address, which is 4 / 8 bytes printf("%d\n", sizeof(&arr[0] + 1));//Take the address of the first element + 1, which is the address of the second element of the array, which is 4 / 8 bytes //The default internal input of strlen function is (const char *string) printf("%d\n", strlen(arr));//Random value. There are no above two cases for arr here. Arr is the address of the first element. Find \ 0, and the \ 0 after f is unknown printf("%d\n", strlen(arr + 0));//Random value printf("%d\n", strlen(*arr));//Arr is the address of the first element, * arr is the first element of the array, 'a' - 97. Strlen gives it an address to start counting from the inside until it meets \ 0. Here, 97 is given to start counting from this place. 97 is returned to strlen as an address. There may be a problem of wild pointer, which is an error code printf("%d\n", strlen(arr[1]));//arr[1]-b-98, also gave 98 to strlen, which is also a wild pointer. The error code is printf("%d\n", strlen(&arr));//Both the first element address and the array address are within the first element address, so the returned value is still a random value printf("%d\n", strlen(&arr + 1));//The principle is the same as the above. It is also a random value, but it starts from the end of the array, which is always 6 different from the above printf("%d\n", strlen(&arr[0] + 1));//Take the address of 'a', a+1 is b, starting from b, which is also a random value return 0; }
#include<string.h> int main() { char arr[] = "abcdef";//a b c d e r \0 printf("%d\n", sizeof(arr));//7 printf("%d\n", sizeof(arr + 0));//arr is the array name. If it is not separately placed in sizeof, it is the address of the first element, that is, the address of A. the address of the first element of a+0 array is 4/8 printf("%d\n", sizeof(*arr));//*The first element of the arr array. one printf("%d\n", sizeof(arr[1]));//1 the second element of the array printf("%d\n", sizeof(&arr));//Is the address of the array 4 / 8 printf("%d\n", sizeof(&arr + 1));//Refers to the address after \ 0, which is 4 / 8 bytes printf("%d\n", sizeof(&arr[0] + 1));//The address of the second element of the array is 4/8byte printf("%d\n", strlen(arr));//6. strlen counts the number of characters before \ 0 printf("%d\n", strlen(arr + 0));//6 printf("%d\n", strlen(*arr));//err, 97 when the address is given to strlen, illegal access printf("%d\n", strlen(arr[1]));98 Here it is strlen,Also illegal access printf("%d\n", strlen(&arr));//6 printf("%d\n", strlen(&arr + 1));//\Start number of addresses after 0. Is a random value printf("%d\n", strlen(&arr[0] + 1));//5 //sizeof calculates the amount of memory an object occupies - in bytes //I don't care what is stored in the memory, only the memory size //sizeof is a unary operator that cannot be simulated like addition, subtraction, multiplication and division //strlen is a library function //Find the length of the string, access the characters backward from the given address, and count the number of characters before \ 0 //Can be simulated return 0; }
int main() { char* p = "abcdef";//p stores the address of the first element of a printf("%d\n", sizeof(p));//4 / 8, p is the address of the first element, and here is the size of the address (pointer) printf("%d\n", sizeof(p + 1));//char * pointer + 1, b address, or find the pointer size, 4 / 8 printf("%d\n", sizeof(*p));//*p is a, 1 printf("%d\n", sizeof(p[0]));//1 p[0]->*(p+0)->*p printf("%d\n", sizeof(&p));//It takes the address of the pointer variable, which is also address 4 / 8 printf("%d\n", sizeof(&p + 1));//&p + 1 is the address after skipping p, char * * q = & p; printf("%d\n", sizeof(&p[0] + 1));//Address of b, 4 / 8 byte s printf("%d\n", strlen(p));//p stores the address of A. give strlen the address of a and count 6 from a printf("%d\n", strlen(p + 1));//The address of b, starting from b, is 5 printf("%d\n", strlen(*p));//err, 97 returned, illegal operation, wild pointer printf("%d\n", strlen(p[0]));//err, 97 returned, illegal operation, wild pointer printf("%d\n", strlen(&p));//This is the address of p. count back to \ 0. It is unknown and should be a random value printf("%d\n", strlen(&p + 1));//Take the address + 1 and access backward. It is also the same as the above. It is a random value printf("%d\n", strlen(&p[0] + 1));//a's address + 1 is b's address, and count to \ 0 is 5 return 0; }
int main() { //Two dimensional array int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//The array list is placed in sizeof(arr), which calculates the size of the whole array, and the bytes are 3 * 4 * 4 = 48 printf("%d\n", sizeof(a[0][0]));//The size of the first element in the first line is 4 printf("%d\n", sizeof(a[0]));//The array list of the first row is placed in sizeof alone, and the size of the first row is calculated, which is 16 printf("%d\n", sizeof(a[0] + 1));//a[0] is not separately placed in sizeof, and there is no direct &, which means that it is the address of the first element in the first line, + 1 is the second address in the first line, and the address is 4 / 8 bytes printf("%d\n", sizeof(*(a[0] + 1)));//*(a[0]+1) represents the second element in the first line, which is 4 printf("%d\n", sizeof(a + 1));//A represents the address of the first element. A is a two-dimensional array, that is, the address of the first line, so a+1 represents the address of the second line, which is also 4 / 8 bytes printf("%d\n", sizeof(*(a + 1)));//This is the address dereference of the second line, which is the second line. The answer is 16 printf("%d\n", sizeof(&a[0] + 1));//a[0] is the array name of the first row, &a[0] is the address of the first row, and the address of the first row plus 1 is the address of the second row, which is also 4 / 8 bytes printf("%d\n", sizeof(*(&a[0] + 1)));//The address of the second line is dereferenced, and the second line accessed is 16 printf("%d\n", sizeof(*a));//A is the address of the first element, that is, the address of the first line, dereference is the first line, and sizeof*a is 16. Here you can also understand the size of the first line of * a - > * (a + 0) - > a [0] printf("%d\n", sizeof(a[3]));//This represents the fourth row of the array, but the array has no fourth row. If there is no error here, it will still be printed //For example: int a=10; // printf("%d\n",sizeof(a));-----4byte // printf("%d\n",sizeof(int));---4byte //When confirming the number of bytes here, we don't really look at the size of a in memory, but know that it is an int type when it is created //Therefore, sizeof(a[3]) above will not access the fourth row of the array at all, but directly know that it is an int[4] is 16 return 0; //Understanding of two-dimensional array: 1 You can think of a two-dimensional array as a one-dimensional array. Each row of a two-dimensional array is a one-dimensional array. }
In short, any array arr[i] is written in this way. For the convenience of beginners, the bottom layer is essentially * (arr+i)
Here are some practical questions:
int main() { int a[5] = { 1, 2, 3, 4, 5 }; int* ptr = (int*)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); return 0; } //What is the result of the program? //Analyze first: //&The combination of a (& and a) indicates the address of the array. The array takes the address and puts it into the array. The pointer is int(*p)[5] //To be consistent with int *ptr (int type), use int * to convert it into an int * pointer. At this time, ptr points to the end of the array, that is, after 5 //ptr-1 means moving forward one position and pointing to 5. The current dereference accesses the integer, that is, 5 //The array name represents the address of the first element, a+1 represents the second element, and the dereference accesses 2
//20 byte s struct Test { int Num;//4 char* pcName;//4 short sDate;//2 char cha[2];//2 short sBa[4];//8 }*p; //Suppose the value of p is 0x100000. What are the values of the expressions in the following table? //It is known that the variable size of the structure Test type is 20 bytes int main() { p = (struct Test*)0x100000;//Although it is a hexadecimal, it is written as an integer, so it is forced to type, and the integer type is changed into a pointer type printf("%p\n", p + 0x1);//The structure pointer + 1 is added with sizeof (the size of the structure) and converted into hexadecimal, which is 0x100014 printf("%p\n", (unsigned long)p + 0x1);//p is converted to an integer. Integer + 1 is plus 1, printf("%p\n", (unsigned int*)p + 0x1);//Converted to a pointer is 4, //The pointer type determines how many bytes are added to the pointer + 1 return 0; }
int main() { int a[4] = { 1, 2, 3, 4 }; int* ptr1 = (int*)(&a + 1); int* ptr2 = (int*)((int)a + 1); printf("%p,%x", ptr1[-1], *ptr2); return 0; }//%X is printed in hexadecimal form,% o is printed in octal form,% p 0 in front of the print address will not be lost. It is necessary to print enough 32 bits, that is, 4 byte s,% x print only significant bits //*A - > * (a + 0) - > a [0], PTR [- 1] = * (ptr-1), which is 4, //vs is the small end storage mode, and the four numbers are stored as 01 00 00 00 00 | 02 00 00 00 | 03 00 00 00 | 04 00 00 // Low high //a is the array name, indicating the address of the first element, that is, 1, and the pointer points to 01 //Plus 1 is the number 1, which points to 00 after 01, followed by int * pointer access //Four bytes at a time is 00 00 02,
If it is%#x printed, 0x will be brought automatically
int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; printf("%d", p[0]); return 0; } //This is a comma expression. It is not a normal two-dimensional array assignment. The normal two-dimensional array assignment number is also enclosed by {} //Here are (,), (,), (,), which is equivalent to five comma expressions. The comma expression only represents the rightmost, so the array initializes 1, 3 and 5 //The array stores //1 3 //5 0 //0 0 //a[0] is neither combined with sizeof alone nor with &, which means that the first value of the first element is 1 and the address is stored in p[0] //p[0]==*(p+0)==1
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; } // 0 0 0 0 0 // 0 0 0 0 0 // 0 0 0 0 0 // P + 4 as an array pointer, the array pointed to by P has four elements, and each element is an integer, so add one and jump four integers at a time. Dereferencing it is to find the four backward elements, and then [2], that is, + 2, is to access the third number from 0 in the other four elements // | // 0 0 0 0 0 // | // p[4][2] // 0 0 0 0 0 // | // &a[4][2] //&p[4][2]==*(*(p+4)+2) //Subtracting the pointer from the pointer will get the number of elements that are different from each other. The difference between the two is four integers. The array increases and changes from small subscript to large subscript, which is equivalent to small address - large address //Yes - 4, - 4 is printed out in% p, - 4 is stored in memory like this 1000 million 0100 (inverse code storage) //When printing, the original code is 1000 million 0011 (inverse code) // 1111 1111 1111 1111 1111 1111 1111 1100 (original code) // f f f f f f f c
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; } //1,2,3,4,5 //6,7,8,9,10 //&AA takes the address of the whole two-dimensional array, which is in the address of the first element+ 1 goes through an array and points to the back of 10. ptr1 is an integer pointer. Subtract 1 and move an integer forward to print 10 //Ptr2, aa represents the address of the first element, which refers to the address of the first row. Adding 1 refers to the address of the second row. Dereferencing the address of the second row is equivalent to getting the array name of the second row * aa==aa[1] represents the block position in 6, and ptr2-1 represents 5
int main() { char* a[] = { "work","at","alibaba" };//The address equivalent to the first character of the string is stored in a ('w'),('a') in the second element and ('a ') in the third element of the array, char** pa = a;//pa stores a, that is, w, and pa + + prints the address of a, that is, at pa++; printf("%s\n", *pa); return 0; }
When printing a string, give an address and start printing directly from the first character stored. If% s prints
int main() { char* c[] = { "ENTER","NEW","POINT","FIRST" };//Pointer array char** cp[] = { c + 3,c + 2,c + 1,c };//first point new enter char*** cpp = cp; printf("%s\n", **++cpp);//point printf("%s\n", *-- * ++cpp + 3);//Operator priority: first + + cpp, then * later -- then * find enter, + 3 find the e of enter, and the er printed by% s printf("%s\n", *cpp[-2] + 3);//Because cpp[-2]==*(cpp-2), this expression can be converted to * * (cpp-2)+3, * * (cpp-2) points to the previous c+3, and then + 3 finds the first printf("%s\n", cpp[-1][-1] + 1);//==*(*(cpp-1)-1)+1; Printed ew return 0; }