目录
一听指针就头大,那就看看基础指针知识吧!
int p; p是普通整形变量
int *p; p是一个返回整形类型的指针。首先从p开始,先与*结合,所以说明p是一个指针,然后再与int结合,说明指针所指向的内容的类型是int型的
int *p[2]; p是一个由返回整型数据的指针所组成的数组。首先从p开始,先与[]结合([]的优先级比*d的优先级高),所以p是一个数组;然后再与*结合,说明数组的元素是指针类型;之后再与int 结合,说明指针所指向的内容的类型是整型
int (*p)[2]; p是一个由整型数据组成的数组的指针。首先从p开始,先与*结合(()的优先级最高),所以p是一个指针;接着再与[]结合,所以指针所指向的内容是一个数组;最后再和int结合,说明数组里的元素类型是整型
int **p; 二级指针不常用,认识即可。首先从p开始,先与*结合,说明p是一个指针,之后再与*结合,说明该指针所指向的元素是指针,最后再与int结合,说明该指针指向的元素是整型
int p(int); p是一个函数,啥,你不会以为是指针吧,那换种写法int main(); int fun();看懂了吧。(int)说明该函数有一个整型变量的参数,再与外面的int结合,说明函数返回值是一个整型
int (*p)(int); p是一个指向有整型参数且返回类型为整型的指针。首先从p开始,先与*结合,说明p是一个指针,接着与()结合,说明指针指向的是一个函数,然后与()里的int 结合,说明函数有一个Int型的参数,最后与最外层的int结合,说明该函数的返回类型是整型。
int *(*p(int))[2]; p是一个参数为整型数据且返回一个指向由指针组成的数组的指针变量的函数。首先从p开始,先与()结合,说明指p是一个函数,与int结合,说明函数参数为整型,然后与*结合,说明函数返回的是一个指针。到最外层,先与[]结合,说明返回的指针指向的是一个数组,之后再与*结合,说明数组内的元素是指针,然后再与int结合,说明指针指向的内容是整型。
过于复杂的数据类型我们慎用,可能会大大降低程序的可读性
遇见指针,问问自己:
只需将声明中的指针名去掉,剩下的部分就是这个指针的类型
int *p | 指针所指向的类型是int* |
int **p | 指针所指向的类型是int** |
int (*p)[2] | 指针所指向的类型是int (*)[2] |
int *(*p(int))[2] | 指针所指向的类型是int*(*)[2] |
决定编译器将你把那片内存区里的内容当做什么类型来看待
只需将声明中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型
int *p | 指针所指向的类型是int |
int **p | 指针所指向的类型是int* |
int (*p)[2] | 指针所指向的类型是int ()[2] |
int *(*p(int))[2] | 指针所指向的类型是int*()[2] |
——或者叫指针所指向的内存区或者地址,在32位平台里,指针本身占据了4个字节的长度
指针可以加上或者减去一个整数。以单元为单位,移动单元= 整数*sizeof(指针所指向的类型)
- char arr[20];
-
- int *p=(int *)arr;
-
- p++;
三问自己:
程序解释:
- char arr[20]="I Love You";
-
- int *p=(int*)arr;
-
- p+=5;
三问自己:
程序解释:
- #include
-
- int main()
-
- {
- char arr[20]="You_love_me";
- char *p=arr;
- char **p2=&p;
- printf("**p2=%c\n",**p2);
- p2++;
- printf("**p2=%c\n",**p2);
-
- return 0;
-
- }
请问输出是什么,害怕我们先入为主,就先正确解释
三问自己:
程序解释:
错解二:输出结果Y和l 。 p2所指向的类型是char*,当执行p2++时,会使指针加上sizeof(char *),有人会认为sizeof(char *)的值为1,违背了在32位平台中,指针变量的大小占4个字节 ,还有人会认为按照4个字节,那么进行一次取值运算不就指向数组中的第五个元素吗?其实不然,详见上面的正解。
特别注意:
浅显理解:有点欢喜冤家,双向奔赴的感觉
- int a=6,*p,**p2;
-
- p=&a;
- *p=12;
- p2=&p;
-
三问自己:
一个表达式的结果如果是一个指针,那表达式就是指针表达式
- int a, b, arr[10];
- int *p1;
- p1=&a //&a是一个指针表达式
-
- int **p2=&p1;//&p1是一个指针表达式
- *p2=&b //*p2和&b都为指针表达式
- int arr[8]={7,6,5,4,3,2,1,0};
- arr[0]等价于*arr
- arr[3]等价于*(arr+3)
数组名可以看成首元素地址,前面已经讲过了指针的加减整数的运算,在这里
- struct student
- {
- int a;
- int b;
- int c;
- };
- struct student st={1,2,3};//对结构体中的a,b,c初始化
-
- struct student *p=&st;
- //声明一个指针,类型是student*
- // 指向类型student
- // 指向结构对象st
通过指针访问:
- float a=0.123;
-
- float *pa1=&a;//正确使用
-
- int *pa2;
在上面的例子中,pa1是正确的,假如我们想让指针pa2指向实数a,应该怎么办?是用下面的语句吗?
pa2=&a;
不对。因为指针 pa2的类型是 int*,它指向的类型是 int。表达式&a的结果是一个指针,指针的类型是 float*,它指向的类型是 float。(前面有讲解)两者不一致,直接赋值的方法是不行的。
为了实现我们的目的,需要进行"强制类型转换":pa2=(int*)&a; 强制类型转换相当于新产生一个指针,并不影响改变原来的各项属性
👍🏻点赞,你的认可是我创作的动力!
⭐收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!