区分const char* p、char* const q、char const *f

229 阅读4分钟

前言

这两个的区别,网上有大量博文,但大多数都是叫你用记忆去强记。今天闲来无聊,我试下用自己的话来尝试解释下这两个的区分。

你需要首先知道的

  • *号跟在数据类型后边,标识指向该类型的指针*号后面跟标识内容
  • 指针表示地址
  • 当指针的地址发生改变后,所指向的值也随之变化(可能不变,概率趋于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* pchar * const qchar 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* pchar* const qchar 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
---------
*/