[C language] Advanced pointers 1


A pointer is a variable used to store an address. The address uniquely identifies a memory space. The size of the pointer is fixed 4/8 bytes (32-bit platform/64-bit platform). Pointers have types. The type of the pointer determines the ±integer step size of the pointer and the permissions during the pointer dereference operation.

1. Character pointer

Among the types of pointers, we know that there is a pointer type called character pointer char*.

int main()
{
    
    
	char ch = 'a';
	char *p = &ch;
	*pc = 'b';
	return 0;
}

Please look at the following code

int main()
{
    
    
	const char* p = "hello world";
	printf("%s\n", p);
	printf("%c\n", *p);
	return 0;
}

Is a string put into the p pointer variable here?
Insert image description here

In fact, it is not the case. The address of the subsequent constant string is actually the address of the first letter. In essence, the address of the first letter h is given to p. In fact, p points to this constant string.

The code const char* p = “hello world”; is particularly easy for us to think that the string hello world is placed in the character pointer p, but the essence is that the address of the first character of the string hello world is placed in p. In fact, it is to store the address of the first character h of a constant string into the pointer variable p.

Please look at the question below

int main()
{
    
    
	char str1[] = "hello world";
	char str2[] = "hello world";
	const char* str3 = "hello world";
	const char* str4 = "hello world";
	if (str1 == str2)
		printf("str1和str2相同\n");
	else
		printf("str1和str2不相同\n");
	if (str3 == str4)
		printf("str3和str4相同\n");
	else
		printf("str3和str4不相同\n");
	return 0;
}

The final output here is:
Insert image description here

Although the contents stored in str1 and str2 are the same, str1 and str2 are two different character arrays with different addresses. Although str3 and str4 are two different character pointers, they both point to the same address, str3 and str4. The storage address is the same.

C/C++ will store constant strings in a separate memory area. When several pointers
point to the same string, they will actually point to the same memory. But when using the same constant string to initialize different arrays, different memory blocks will be opened up. So str1 and str2 are different, str3 and str4 are the same.

2. Array pointer

2.1 Definition of array pointer

If a pointer points to an array, we call it an array pointer.
We can also define a pointer to an array, for example:

int arr[] = {
    
     9, 15, 10, 8, 2 };
int *p = arr;

arr itself is a pointer and can be directly assigned to the pointer variable p. arr is the address of the 0th element of the array, so int *p = arr; can also be written as int *p = &arr[0];. In other words, the three ways of writing arr, p, & arr[0] are equivalent, and they all point to the 0th element of the array, or to the beginning of the array.
Which of the following codes is an array pointer?

int *p1[10];
int (*p2)[10];

The answer is int (*p2)[10];
because p2 is first combined with *, indicating that p2 is a pointer variable, and then points to an array of 10 integers. So p2 is a pointer, pointing to an array, called an array pointer.
Note: [] has a higher priority than *, so () must be added to ensure that p is combined with * first.

2.2 &array name VS array name

int arr[10];

What are arr and &arr?
We know that arr is the array name, and the array name represents the address of the first element of the array. So what exactly is the &arr array name? Let's look at a piece of code:

int main()
{
    
    
	int arr[10] = {
    
    0};
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr);
	return 0;
}

The running results are as follows:
Insert image description here

It can be seen that the address printed by the array name and &array name is the same. Are all three the same? Let’s look at another piece of code:

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

Insert image description here

According to the above code, we found that in fact, although the values ​​​​of &arr and arr are the same, their meanings should be different.
In fact: &arr represents the address of the array, not the address of the first element of the array. The type of &arr is: int(*)[10], which is the address of an array pointer type array + 1, skipping the size of the entire array, so the difference between &arr+1 and &arr is 40.
For array names, &arrayname gets the address of the array.

2.3 Use of array pointers

How are array pointers used? Since the array pointer points to an array, the address of the array should be stored in the array pointer.

void print_arr(int(*arr)[5], int row, int col)
{
    
    
	int i = 0;
	for (i = 0; i < row; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < col; j++)
		{
    
    
			printf("%d ", *(*(arr+i)+j));
		}
		printf("\n");
	}
}
int main()
{
    
    
	int arr[3][5] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	print_arr(arr, 3, 5);
	return 0;
}

The array name arr represents the address of the first element. But the first element of the two-dimensional array is the first row of the two-dimensional array. So the arr passed here is actually equivalent to the address of the first line, which is the address of a one-dimensional array. Can be received by array pointer

3. Array parameter passing and pointer parameter passing

3.1 One-dimensional array parameter transfer

void test1(int arr[])
{
    
    }
void test1(int arr[10])
{
    
    }
void test1(int *arr)
{
    
    }
void test2(int *arr[20])
{
    
    }
void test2(int **arr)
{
    
    }
int main()
{
    
    
	int arr[10] = {
    
    0};
	int *arr2[20] = {
    
    0};
	test1(arr);
	test2(arr2);
	return 0;
}

3.2 Two-dimensional array parameter transfer

void test(int arr[3][5])
{
    
    }
void test(int arr[][5])
{
    
    }
void test(int (*arr)[5])
{
    
    }
void test(int **arr)
{
    
    }
int main()
{
    
    
	int arr[3][5] = {
    
    0};
	test(arr);
}

Summary: When passing parameters through a two-dimensional array, the design of function parameters can only omit the first [] number. Because for a two-dimensional array, you don't need to know how many rows there are, but you must know how many elements are in a row. This makes calculations easier.

3.3 First-level pointer parameter passing

void print(int *p, int sz)
{
    
    
	int i = 0;
	for(i=0; i<sz; i++)
	{
    
    
		printf("%d\n", *(p+i));
	}
}
int main()
{
    
    
	int arr[10] = {
    
    1,2,3,4,5,6,7,8,9};
	int *p = arr;
	int sz = sizeof(arr)/sizeof(arr[0]);
	//一级指针p,传给函数
	print(p, sz);
	return 0;
}

3.4 Secondary pointer parameter passing

void test(int** ptr)
{
    
    
	printf("num = %d\n", **ptr);
}
int main()
{
    
    
	int n = 10;
	int*p = &n;
	int **pp = &p;
	test(pp);
	test(&p);
	return 0;
}

4. Function pointer

First look at a piece of code:

void test()
{
    
    
	printf("hello\n");
}
int main()
{
    
    
	printf("%p\n", test);
	printf("%p\n", &test);
	return 0;
}

The output result:
Insert image description here
function name and & function name are both the address of the function.
So how do we store the address of the function? The answer is function pointers.

void (*p)() = &test;

p is first combined with *, indicating that p is a pointer. The pointer points to a function. The pointed function has no parameters and the return value type is void.
Take a look at the function below. How do you point to it with a pointer?

int add(int a,int b)
{
    
    
	return a + b;
}

Answer:

int (*p)(int, int) = &add;

call function pointer
Insert image description here

Thank you all for watching, I hope my article can help you. Thank you for your support, let’s work together! ! !

Guess you like

Origin blog.csdn.net/qq_58032742/article/details/132090313