指针常量
是类型为指针的常量,本质还是常量,只不过数据类型是指针,指向确定后不能改变指向,指向地址的内容可以发生改变,在定义时也必须赋值好初值,否则就算是NULL,也不能再改变了
#include <stdio.h>
int main(){
int a=10;
int c=5;
int * const b=&a;
printf("b的值:%d\n",*b);
//b=&c; 非法,指针常量不能改变指向了
//*b=5; 可行,指向的内容可以通过指针改变
a=c;// 可以,因为指向的内容可以改变
printf("a改变后 b的值:%d\n",*b);
return 0;
}
如果改变了指向,会提示错误,该变量只读,也就是常量的意思
常量指针
是指向某个常量的指针,指向的内容不能通过指针改变,只能通过指向的变量本身来改变,本质还是指针,可以改变指向
#include <stdio.h>
int main(){
int a=10;
int c=5;
int const *b=&a;
printf("b的值:%d\n",*b);
b=&c;
//*b=5; 非法,常量指针不能通过指针来改变值
a=c;// 可以,因为指向的内容可以改变
printf("a改变后,或b改变指向后 b的值:%d\n",*b);
return 0;
}
如果通过指针改变了值,会提示错误
字符串与指针常量
这里有一个例子,定义一个指针常量c指向一个字符串a,当该字符串a被赋值为另一个字符串b,那么p打印出来为a还是为b呢?
#include <stdio.h>
int main(){
char * a="abc";
char * b="efg";
char *const c=a;
printf("c指向a后:%s\n",c);
a=b;
printf("a内容被赋值b后:%s\n",c);
return 0;
}
可以看到这当a赋值为b后并没有改变c,因为字符串本质也是指针,c指向a指向的空间,下一步a指向了b的空间,但是c的指向没改变,所以c的值并没有改变,我们可以看看把他们的地址都打出来,就一目了然了。
#include <stdio.h>
int main(){
char * a="abc";
char * b="efg";
char *const c=a;
printf("c指向a后:%s\n",c);
printf("b地址:%p\n",b);
printf("a地址:%p\n",a);
printf("c地址:%p\n",c);
printf("------------------\n");
a=b;
printf("a地址:%p\n",a);
printf("c地址:%p\n",c);
printf("a内容被赋值b后:%s\n",c);
return 0;
}
这里可以直观的看到,c在整个过程中地址都没有任何的改变,但是a虽然被赋值了,但是并不会影响到c的输出
数组与指针常量
数组的地址是否能改变,也就是数组是指针常量还是常量指针,我们可以用代码来验证一下
#include <stdio.h>
int main(){
int a[]={1,2,3,4,5};
int *p;
p=a;
// printf("直接对数组操作:%d\n",*(a++));//非法,数组的地址是指针常量,不能改变指向,也就是不能偏移
printf("对指针操作:%d\n",*(p++));
return 0;
}
如果直接对数组操作会发生lvalue required as increment operand错误,因为数组是指针常量
当然这里只是为了举例子而让p++,实际中一般不会这样操作,因为这样一直操作下去的话,地址就会偏移到数组越界的范围了