[C language] In-depth analysis of the relationship between pointers and arrays


1. Array name and & array name

Second, the character pointer

1. A character pointer to the first element of a character array char* p=arr

2. A character pointer to a constant string const char* p="abc"

3. Pointer array int* p[3]={arr1,arr2,arr3}

4. Array pointer int(*p)[10]=&arr

Five, array parameters

1. One-dimensional array parameter transfer

2. Two-dimensional array parameter transfer

Six, pointer parameter

1. First-level pointer parameter transfer

2. Second-level pointer parameter transfer

Seven, function pointer

1. Understanding of the two codes

2. Rename function pointer

3, the use of function pointers - callback function

Eight, function pointer array - purpose: transfer table

Nine, function pointer array pointer


1. Array name and & array name

Difference: The array name indicates the address of the first element, and adding 1 to the address indicates skipping the size of a data type.

The & array name means that the address of the entire array is taken out, and adding 1 to the address means skipping the length of an array.

For example: arr[] needs to be pointed to by an integer (etc.) pointer, and &arr[] needs to be pointed to by an array pointer.

The array name usually represents the address of the first element, with two exceptions:

1. sizeof (array name), where the array name represents the address of the first element of the array.

2. & array name, indicating that this array is taken out.

Second, the character pointer

1. A character pointer to the first element of a character array char* p=arr

#include <stdio.h>
int main()
{
	char arr[5] = "abc";
	char* p = arr;
	printf("%s", p);//打印abc
	return 0;
}

The array name is the address of the first element, where the pointer p points to the address of the first element 'a' of the arr array, and the string can be printed in the form of %s through the pointer p.

2. A character pointer to a constant string const char* p="abc"

#include <stdio.h>
int main()
{
	const char* p = "abc";//字符串abc为常量字符串
	printf("%s", p);
	return 0;
}

Because "abc" is a constant string and cannot be modified, the pointer p needs to be modified with const. If there is no const, the program will hang directly when the .c file is running, and the .cpp file will be more strict, and an error will be reported directly.

3. Pointer array int* p[3]={arr1,arr2,arr3}

An array of pointers is essentially an array, an array of pointers.

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,7,5,8,99 };
	int* p[3] = { arr1,arr2,arr3 };
	for (int i = 0;i < 3;i++)
	{
		for (int j = 0;j < 5;j++)
		{
			//printf("%d ", p[i][j]);
            //printf("%d ", *(*(p+i) + j));//p[i]可以写成*(p+i)
			printf("%d ",*(p[i]+j));//解释如下图
		}
		printf("\n");
	}
	return 0;
}

All three ways of printing pointer arrays are possible. The code here is similar to a two-dimensional array, and the first element of the array is the first row. The detailed analysis is as follows:

4. Array pointer int(*p)[10]=&arr

An array pointer is a pointer to an array.

int(*p)[10]=&arr, the type of the array pointer p is int(*)[10] (remove p, that is, the type). Here pointer +1 skips one array size.

#include <stdio.h>
print(int(*p)[5], int r, int c)//接收的是指向一维数组的数组指针
{
	for (int i = 0; i < r;i++)
	{
		for (int j = 0; j < c; 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,5,4,6,7,9,8,4,2,5,4,5,4,5,6 };
	print(arr, 3, 5);//传过去的是二维数组
	return 0;
}

The understanding of the printing method is the same as the previous example. Note that the first element of the two-dimensional array is the first row.

Let's look at another example: int(*p[10])[5], which is an array that stores array pointers, and the type of array elements is int(*)[5].

Five, array parameters

1. One-dimensional array parameter transfer

void test(int arr[])//一维数组传参,数组接收
{}
void test(int arr[10])//一维数组传参,数组接收,10可有可无
{}
void test(int* arr)//一维数组传参,指针接收
{}
int main()
{
	int arr[10] = { 0 };
	test(arr);
}
void test2(int* arr[20])//指针数组传参,指针数组接收,20可有可无
{}
void test2(int** arr)//传过来的是一级指针的指针,当然可以用二级指针接收
{}
int main()
{
	int* arr2[20] = { 0 };
	test2(arr2);
}

2. Two-dimensional array parameter transfer

void test(int arr[3][5])//二维数组传参,二维数组接收
{}
void test(int arr[][])//错误,行不能省略
{}
void test(int arr[][5])//二维数组传参,二维数组接收
{}
void test(int *arr)//错误,传过来的是第一行的地址,相当于一维数组的地址,不能用一级指针接收
{}
void test(int* arr[5])//错误,不能用指针数组接收
{}
void test(int (*arr)[5])//可以用数组指针接收
{}
void test(int **arr)//错误,传过来的是一维数组的指针,不能用二级指针接收,二级指针是指向一级指针的指针
{}
int main()
{
 int arr[3][5] = {0};
 test(arr);//传过来的相当于第一行的地址
}

Six, pointer parameter

1. First-level pointer parameter transfer

void text(int* p)
{}
int main()
{
	int a = 0;
	int* pa = &a;
	int arr[10] = { 0 };
	text(&a);//可以传整型变量的地址
	text(pa);//可以传一级指针的地址
	text(arr);//可以传整型数组的地址
	return 0;
}

As long as the essence passed is a first-level pointer, it can be received with a first-level pointer.

2. Second-level pointer parameter transfer

void text(int** p)
{}
int main()
{
	int* p1 = NULL;
	int** p2 = NULL;
	int* arr[10];
	text(&p1);//可以传一级指针的地址
	text(p2);//可以传二级指针
	text(arr);//可以传指针数组
	return 0;
}

Seven, function pointer

For function names and & function names, their addresses are the same, and there is essentially no difference.

When calling a function using a function value pointer, you can call p as a function name, and dereferencing is meaningless.

1. Understanding of the two codes

( *( void (*)() )0 )();

The above code is a function call, first cast 0 to the function pointer type, the function pointer has no parameters, and the return value is void. Since function pointer dereference is meaningless, this * is optional here. The whole code means a function call to the function at address 0.

void ( *signal( int , void(*)(int) ) )(int);

The above code is a function declaration.

signal is the function name, its parameters are int and function pointer void(*)(int), and the return type is function pointer void(*)(int).

2. Rename function pointer

typedef void(*pf_t)(int);
pf_t signal(int,pf_t);

Rename void(*)(int) type to pf_t.

The above function can use pf_t instead of void(*)(int).

3, the use of function pointers - callback function

int Add(int a, int b)
{}
int Sub(int a,int b)
{}
int Mul(int a, int b)
{}
int Div(int a, int b)
{}
int calc(int(*p)(int,int))
{
	return p(1, 2);
}
int main()
{
	calc(Add);
	return 0;
}

When there are multiple functions with the same parameter and return type, function pointers can be used to call these functions on demand to reduce code redundancy.

Eight, function pointer array - purpose: transfer table

An array of function pointers is an array of function pointers.

int Add(int a, int b)
{}
int Sub(int a,int b)
{}
int Mul(int a, int b)
{}
int Div(int a, int b)
{}
int main()
{
	int input,x,y;
    scanf("%d%d%d",&input,&x,&y);
    //int(*p)(int, int) = Add;
	int(*arr[4])(int,int) = {Add,Sub,Mul,Div};//数组arr的类型直接将函数指针的p替换即可
    int ret=arr[input](x,y);//使用函数指针数组对函数进行调用——转移表
	for (int i = 0; i < 4; i++)//函数指针数组的遍历调用
	{
		int ret = arr[i](8, 4);
    }
	return 0;
}

The function pointer array can be used to call functions with the same formal parameters and return types, and the jump function of the function can be realized in actual use, so it is called a transfer table and has great use value.

Nine, function pointer array pointer

int main()
{
    int(*p)(int, int) = Add;//p是函数指针
	int(*arr[4])(int,int) = {Add,Sub,Mul,Div};//arr是函数指针数组
    int(*(*parr))(int,int)=&arr//parr是函数指针数组指针
	return 0;
}

The writing method can imitate the writing according to the upper-level pointer/array type.

Guess you like

Origin blog.csdn.net/gfdxx/article/details/125128344