一
*p = &a
默认
p是指针
a是变量
a、&a、p、*p、*(&p)、*(&a)、&(*p)、&(*a)
a:变量
&a:取变量a的地址
p:指向a的地址
*p:指向a的地址的值
*(&p):先取p的地址后再解引用,*(&p)等价于p
*(&a):先取a的地址后再解引用,*(&a)等价于a
&(*p):先对p解引用回a后再取地址,&(*p)等价于p
&(*a):先对a解引用后再取地址,但默认a是常量,故此写法为 非法
二
*p++、*(p++)、(*p)++、++*p、*++p
*p++:int *p++可写作int* p++
即:p为int*类型,p又是指向a的地址,p++表示a的地址后置自增1
若:
int main() {
int arr[3] = {1,2,3};
int *p = arr;
int a = *p;
int b = *p++;
printf("%d %d",a,b);
return 0;
};

运行到第3行时,p指向arr首地址arr[0]

运行到第5行时,p指向arr[1],即地址自增1,但b却为1
结论:
*p++运行时会先取当前所指向的值(arr[0]=1)作为表达式的结果(a=1),后地址自增1,即p指向arr数组第二个元素
*(p++)
int main() {
int arr[3] = {1,2,3};
int *p = arr;
int a = *p;
int b = *(p++);
printf("%d %d",a,b);
return 0;
};


结论:
*p++等价于*(p++)
(*p)++
*p本身就是p所指向的值,此可类比为a++
int main() {
int arr[3] = {1,2,3};
int *p = arr;
int a = *p;
int b = (*p)++;
printf("%d %d",a,b);
return 0;
};


结论:
(*p)++执行时也会取当前指向地址的值(arr[0]=1)但并不会改变地址的指向,只是会更新此地址原本的数值(1变2)
++*p
注意可知:++*p等价于++(*p),进一步类比为++a。先自增后取值,不会改变指向的地址
int main() {
int arr[3] = {1,2,3};
int *p = arr;
int a = *p;
int b = ++*p;
printf("%d %d",a,b);
return 0;
};


*++p
先自增p的地址后取新地址的数值


三
XX指针、指针XX
XX指针:本质是指针
如:
常量指针:const int* p; 可改指向,内容不可修改
函数指针:void (*fun)(); 存放函数入口地址,用以调用函数
数组指针:int (*p)[];指向整个数组的指针,存储数组首地址
指针XX:本质是XX
如:
指针常量:int* const p; 本质是常量,则内容不可修改,但指向内容可以修改
指针函数:void* fun();本质是函数,返回值为指针类型
指针数组:int* p[];本质是数组,每个元素都是指针



