前言
这两个的区别,网上有大量博文,但大多数都是叫你用记忆去强记。今天闲来无聊,我试下用自己的话来尝试解释下这两个的区分。
你需要首先知道的
*号跟在数据类型后边,标识指向该类型的指针;*号后面跟标识内容。- 指针表示地址
- 当指针的地址发生改变后,所指向的值也随之变化(可能不变,概率趋于0)
//例如:
char* p;//P为指向char的指针,是一个地址
- 以下区分基于一个原则:const最近原则,简单来说,就是const的右边最近的是什么类型,该类型就只读,值得注意的是:若const右边为
*号,由于单个*号无法表示标识内容,因此要视*号和其后面的标识内容为整体。
//例如:
const char p;//const右边为char,所以char只读,而p为char型变量,所以p值只读
char const *p;//const右边为*,由于单个*号无法表示标识内容,因此将(*p)视为一个整体,所以p指向的值只读,p的地址可改
char* const p;//const右边为p,而p是指向char的指针,所以p的地址只读,p指向的值可改
区分
通过上面的基本了解,应该能大致判断出const char* p、char * const q与char const *f,下边我用自己的话来区分一下
const char* p;
//const 的右边是 char, 所以P的地址可修改,q指向的值只读
//这里为什么不是p的地址只读,值可修改吗?难道const修饰的不是char*吗?
//答:这里不是char* 的原因是,*号只是标识指向char的指针,况且char与*号可以不连写在一起,
//中间也可以写一堆空格,比如写出 const char *p; 因此离const最近的是char。
char* const q;
//const的右边是q, 而q是指向char的指针,因此q的地址只读,q指向的值可改
char const *f;
//const的右边是*号,但单个*号无法表示标识内容,所以const的右边最近的为(*q),因此f的指向值只读,f的地址可改
通过上边代码解释可以得出以下的表格:
| const char* p | char* const q | char const * f |
|---|---|---|
指针p指向的的值只读,指针p的地址可改 | 指针q的地址只读,指针q所指向的值可改 | f指向的值只读,f的地址可改 |
测试代码
#include <stdio.h>
int main()
{
char a = 'A';
char b = 'B';
char c = 'C';
const char* p = &a; //指针p的指向的值只读,指针p的地址可改
char* const q = &b;//指针q的地址只读,指针q所指的值可改
char const *f = &c;//指针f指向的值只读,指针f的地址可改
printf("初始:\n");
printf("a的地址:%p\n",&a);
printf("p的地址:%p\n",p);
printf("p指向的值:%c\n", *p);
printf("---------\n");
printf("b的地址:%p\n",&b);
printf("q的地址:%p\n",q);
printf("q指向的值:%c\n",*q);
printf("---------\n");
printf("c的地址:%p\n",&c);
printf("f的地址:%p\n",f);
printf("f的指向的值:%c\n",*f);
printf("---------\n");
printf("修改:\n");
//printf("修改p指向的值(将p指向的值改为d):\n");
//*p = 'd';//报错:*p只读
//printf("p指向的值:%c\n", *p);
//printf("---------\n");
printf("修改p的地址(将p的地址改为c的地址):\n");
p = &c;
printf("p的地址:%p\n",p);
printf("p指向的值:%c\n", *p);
printf("---------\n");
//printf("修改q的地址(将q的地址改为c的地址):\n");
//q = &c;//报错:q只读
//printf("p的地址:%p\n",q);
//printf("p指向的值:%c\n", *q);
//printf("---------\n");
printf("修改q的值(将q指向的值改为c):\n");
*q = 'c';
printf("q的地址:%p\n",q);
printf("q指向的值:%c\n", *q);
printf("---------\n");
//printf("修改f指向的值(将f指向的值改为e):\n");
//*f = 'e';//报错:*f只读
//printf("f指向的值:%c\n", *f);
//printf("---------\n");
printf("修改f的地址(将f的地址改为a的地址):\n");
f = &a;
printf("f的地址:%p\n",f);
printf("f指向的值:%c\n", *f);
printf("---------\n");
return 0;
}
//输出(编译工具:[C 在线工具 | 菜鸟工具 (runoob.com)](https://c.runoob.com/compile/11/))
/*
初始:
a的地址:0x7ffe7287685f
p的地址:0x7ffe7287685f
p指向的值:A
---------
b的地址:0x7ffe7287685e
q的地址:0x7ffe7287685e
q指向的值:B
---------
c的地址:0x7ffe7287685d
f的地址:0x7ffe7287685d
f的指向的值:C
---------
修改:
修改p的地址(将p的地址改为c的地址):
p的地址:0x7ffe7287685d
p指向的值:C
---------
修改q的值(将q指向的值改为c):
q的地址:0x7ffe7287685e
q指向的值:c
---------
修改f的地址(将f的地址改为a的地址):
f的地址:0x7ffe7287685f
f指向的值:A
---------
*/