Pointer type
The pointer type and the type pointed to by the pointer are two concepts.
From a grammatical point of view: For pointer declaration statements, remove the pointer name, and the rest is the pointer type; remove the pointer name and the preceding * sign, and the rest is the type pointed to by the pointer.
Pointer declaration statement | Pointer type | The type pointed to by the pointer |
---|---|---|
int *p; | int* | int |
int **p; | int** | int* |
int (*p)[ 5 ]; | int ( * )[ 5 ] | int ()[ 5 ] |
int *(*p)[ 5 ]; | int *( * )[ 5 ] | int *()[ 5 ] |
As long as there is a section of memory, and the content stored in this section of memory has a fixed type, you can define a pointer to it.
The type pointed to by the pointer can be verified by measuring the space occupied by *p sizeof(*p)
.
1. Pointer to a one-dimensional array: int (*p)[10]
The declaration indicates that p is a pointer to an integer array with a "length" of 10. That is to say, the unit of addition and subtraction is an entire array.
For a two-dimensional array:
the operating unit of a two-dimensional array is a one-dimensional array. Therefore, when the pointer points to a one-dimensional array assignment can be directly assigned to the array name: int (*p)[10] = array;
(& and * are inverse operations, it can also be written as: int (*p)[3] = &a[0];
)
after the assignment p viewed as a two-dimensional array can be p [ 0][0] Such operations, but pay attention to the position pointed to by the p pointer (the position pointed to by p will be used as the origin) . As a two-dimensional array, the unit element in the p++ operation is a one-dimensional array, so the p++ operation can switch to the next one-dimensional array; (*p) can be regarded as a one-dimensional array.
int a[3][3] = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
int (*p)[3] = a;
printf("%d\n", p[0][0]);//输出1
printf("%d\n", (*p)[1]);//输出2 (*p)[1]相当于a[0][1]
p ++;
printf("%d\n", (*p)[1]);//输出5 此处(*p)[1]相当于a[1][1]
printf("%d\n", (*(p+1))[1]);//输出8
printf("%d\n", *(*p+1));//输出5 *p可视作一维数组
printf("%d\n", p[0][0]);//输出4 p所指的位置不再是a[0][0]而是a[1][0],因此导致p[0][0]的值与a[0][0]不同
For one-dimensional arrays:
If you assign the array name directly during assignment, the array name is actually just the address of the first element, and the pointer only points to a single array element. In order to point to the entire array, the one-dimensional array should be "enlarged" when assigning: int (*pt)[10] = &array;
(using the & operator) (* operator makes more detailed, & operator is the opposite)
After assignment, p can be regarded as a first A "two-dimensional array" with a dimension of 0 can perform operations such as p[0][1]; (*p) can be regarded as a one-dimensional array. Because p already points to the entire one-dimensional array, the p++ operation has no meaning.
int a[9] = {
1, 2, 3, 4, 5, 6, 7, 8, 9};
int (*p)[9] = &a;
printf("%d\n", p[0][1]);//输出2
printf("%d\n", (*p)[1]);//输出2 (*p)[1]相当于a[1]
2. Pointer to function
A function has a physical memory address that can be assigned to a pointer. The function name of a function is a pointer, which is the entry point of the function. The function can be called through the function name, or through the pointer to the function.
The definition form, for example, int (*p)(int i, int j);
can also be simplified to int (*p)(int, int);
indicate that p points to a function whose return value is an integer and requires two integer parameters. After the definition, assign the function name to the pointer, and (*p) can be used as the function name .
#include<stdio.h>
int max(int x, int y)
{
return(x > y ? x : y);
}
int main()
{
int (*p)(int, int);//定义一个指向函数的指针变量
int a, b, c;
p = max;//将函数的入口地址赋给p,此时p和max都指向函数的开头
scanf("%d%d", &a, &b);
c = (*p)(a, b);//调用*p就是调用max函数
printf("%d", c);
return 0;
}
Using pointers to functions can call different functions depending on different situations, which is very convenient.
#include <stdio.h>
int max(int x, int y)
{
return(x > y ? x : y);
}
int min(int x, int y)
{
return(x < y ? x : y);
}
int main()
{
int (*p)(int, int);//定义一个指向函数的指针变量,它可以指向 函数类型为int,且有两个int型参数 的函数
int a, b, c, n;
scanf("%d%d%d", &a, &b, &n);
//函数名代表函数的入口地址(起始地址、指针)
if (n == 1) p = max;//将函数的指针赋给指针变量,只需给出函数名即可
if (n == 0) p = min;//根据输入的n的值来判断调用哪个函数
c = (*p)(a, b);//(*p)即p所指向的函数名。 表达式唯一(方便!)
printf("%d", c);
return 0;
}
Note that the distinction int *函数名(参数列表)
with the int (*p)(参数列表)
former defines a function that returns a pointer, while the latter defines a pointer to a function.
3. Pointer to the structure
Just define the type of the pointer when it is the created structure type, after the definition (*p) is equivalent to the set structure variable.
struct Student
{
long num;
char name[20];
}s[3] = {
{
10101, "Tom"}, {
10102, "Jack"}, {
10103, "Join"}};
struct Student *p;
for (p = s; p < s + 3; p ++)//将结构体数组的地址赋给指针变量
{
printf("%ld\t%s\n", (*p).num, (*p).name);//(*p)表示p指向的结构体变量,(*p).num表示p所指向的结构体变量中的成员num
printf("%ld\t%s\n", p->num, p->name);//更加形象化地表示"指向",两种表示的效果相同
}