Advanced pointer explanation (1)

1. Pointer review
1. A pointer is a variable used to store an address, and the address uniquely identifies a piece of memory space
2. The size of the pointer is a fixed 4/8 bytes (32-bit platform/64-bit platform)

#include<stdio.h>
void test(int a[])
{
    
    
	printf("%d",sizeof(a)/sizeof(a[0]);
int main()
{
    
    
	int a[10]={
    
    0};
	test(a);
}

//若为32位平台,运行结果为1;64位则为2

3. Pointers are typed. The type of the pointer determines the step size of the ± integer of the pointer, and the authority when the
pointer is dereferenced
. 4. Pointer operation 2. Pointer advanced
1. Character pointer

Three representation methods

#include<stdio.h>
int main()
{
    
    
	char ch='w';
	char* pc=&ch;
	return 0;
}
#include<stdio.h>
int main()
{
    
    
	char arr[]="abcdef";
	char* pc=arr;
	printf("%s\n",arr);
	printf("%s\n",pc);
}
#include<stdio.h>
int main()
{
    
    
	const char* p="abcdef"; //"abcdef"为常量字符串,注意不能修改
	printf("%c\n",*p);
	printf("%s\n:,p);	
}

Next look at a question

#include<stdio.h>
int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	const char* p1 = "abcdef";
	const char* p2 = "abcdef";
	if (arr1 == arr2)
	{
    
    
		printf("hehe\n");
	}
	else
	{
    
    
		printf("haha\n");
	}
	if (p1 == p2)
	{
    
    
		printf("hehe\n");
	}
	else
	{
    
    
		printf("haha\n");
	}
	// 打印结果 haha
	//		   hehe	

The pointer means that the address is the same is because the string is stored in the constant area of ​​the memory (its content cannot be modified), so both p1 and p2 store the address of the string constant area,
and the array representation will be stored in the constant area Copy the string to the array in the stack area (the data in the stack area can be changed), so the addresses of the two arrays are not the same.
Some students may not know the four areas of memory. You can read this article Better understand the
four-zone memory model (stack, heap, code, global)

2. Pointer array The
pointer array is an array, used to store pointers

#include<stdio.h>
int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5 };
	int arr2[] = {
    
     2,3,4,5,6 };
	int arr3[] = {
    
     3,4,5,6,7 };
	int* parr[] = {
    
     arr1,arr2,arr3 };
	// []的优先级要高于 *号,parr先与[]结合,说明parr是个数组,里面存的元素类型是int *类型
	int i = 0;
	for (i = 0; i < 3; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < 5; j++)
		{
    
    
			printf("%d ", *(parr[i] + j));
		}
	}
	printf("\n");
}
//打印结果  1 2 3 4 5
//         2 3 4 5 6
//         3 4 5 6 7

parr[i] corresponds to three pointer variables, which store the address of the first element of arr1, arr2, arr3. Parr
[i]+j represents the address of each element in the array, and the content is obtained after dereference

3. Array pointer
Array pointer is a pointer, a pointer to an array

int arr[10]={
    
    0};
int(*p)[10]=&arr;

Explanation: p is combined with *, indicating that p is a pointer variable, and then points to an array of 10 integers, so p is a pointer, which points to an array, which is called an array pointer
. Note here that the priority of [] It is higher than the * sign, so parentheses must be added to ensure that p is combined with * first.

Next, let's look at the confusing problem:
&array name vs array name

For the following array

int arr[10];

What are arr and &arr?
We know that arr is an array name, and the array name represents the address of the first element of the array.
So what is &arr?

Let's look at the following piece of code

#include<stdio.h>
int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
}

From the result, we can see that the address printed by the array name and & array name are the same.
Are the two the same?

Let's look at a piece of code

#include<stdio.h>
int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("arr=%p\n", arr);
	printf("&arr=%p\n", &arr);
	printf("arr+1=%p\n", arr + 1);
	printf("&arr+1=%p\n", &arr + 1);
}

According to the above code, we can find that although the value of &arr and arr are the same, the meaning is not the same.
In fact, &arr represents the address of the array, not the address of the first element of the array (please understand carefully here)
the address of the array plus 1. Skip the size of the entire array, so the difference between &arr+1 and &arr is 40.

4. The use of array pointers

Look at this piece of code

#include<stdio.h>
int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int(*p)[10] = &arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", (*p)[i]); // *p==arr
	}
	printf("\n");
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", *(*p + i));
	}
	printf("\n");
}
// 1 2 3 4 5 6 7 8 9 10
// 1 2 3 4 5 6 7 8 9 10

The key here is to understand * p==arr , we dereference the address of an array is equivalent to get the array name

#include<stdio.h>
void print2(int(*p)[5], int x, int y)
{
    
    
	int i = 0;
	for (i = 0; i < x; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < y; j++)
		{
    
    
			printf("%d ", p[i][j]);
			printf("%d ", *(p[i] + j));
			printf("%d ", *(*(p + i) + j));
			printf("%d ", (*(p + i))[j]);
		}
		printf("\n");
	}
}
int main()
{
    
    
	int arr[3][5] = {
    
     {
    
    1,2,3,4,5},{
    
    2,3,4,5,6},{
    
    3,4,5,6,7} };
	print2(arr, 3, 5);
}

We know that the array name is the address of the first element of the array, so what type of pointer should be used when passing the two-dimensional array name?

In fact, we can think of this two-dimensional array as a one-dimensional array, each row as an element, then the array I wrote has three elements, each element is a one-dimensional array, the address of the first element is The address of a one-dimensional array of type int[5]. So we use the array pointer to receive the address of the array when passing parameters.

The above four printing methods are equivalent, the first one is easy to understand, let’s look at the following three methods

*(p[i]+j)

p is the address of the one-dimensional array in the first row, p[i] is the dereference of the array address in the (i+1)th row. As mentioned above, dereferencing the array address is equivalent to getting the array name, and the array name is Is the address of the first element of each row of the array, so p[i]+j is the address of each element, dereference again to get the content.

*(*(p+i)+j)

p is the address of the one-dimensional array in the first row. As mentioned earlier, the array address is increased by 1, skipping the entire array size, then (p+i) represents the address of the one-dimensional array in each row, after dereference *(p+i) It is the array name of each row of one-dimensional array, that is, the address of the first element of each row of one-dimensional array, *(p+i)+j represents the address of each element, and its content is obtained after dereference

Through the above two comparisons, it is not difficult to find:
p[i] is equivalent to *(p+i)

(*(p + i))[j]

*(p + i) represents the address of the first element of each row of a one-dimensional array, then each element in the two-dimensional array can also be obtained in this way.

Guess you like

Origin blog.csdn.net/DR5200/article/details/112299601