const《指针常量和常量指针》记录下之前理解错误的地方

常量指针:

const char *p1 = s;

char const *p1 = s;两者等价。 

指针可改变,该指针变量指向的内容不能改变,是只读的。

先看一段代码:

#include <stdio.h>

void constTestFunc(void)
{
	const char s[] = "const";
	//常量指针
	//const char *p1 = s;
	char const *p1 = s;
    printf("p1:%c p1 addr:%p\n", *p1, p1);
	p1[3] = 'g';
}
int main(void)
{
	constTestFunc();
	return 0;
}

        先思考一下,上面代码能不能运行成功,p1是个常量指针,也就是p1指向的内容不能变,p1的地址是可以改变的。p1[3] = 'g' ,那p1+3处的内容能不能改变呢?

        编译可以发现,会提示这个位置也是只读的。

error: assignment of read-only location ‘*(p1 + 3u)’

但是,我如果用另外一个指针去指向这个偏移后的地址,却是可以改变的:

#include <stdio.h>

void constTestFunc(void)
{
	char *q = NULL;
	const char s[] = "const";
	//常量指针
	const char *p1 = s;
	//char const *p1 = s;
	printf("p1:%c p1 addr:%p\n", *p1, p1);
	//p1[3] = 'g';
	//*(p1+3) = 'g';
	q = (char *)(p1 + 3);
	*q = 'g';
	printf("q:%c q addr:%p\n",*q,q);
}
int main(void)
{
	constTestFunc();
	return 0;
}

 那么*(p1 +3) = 'g' 为什么不行呢,意思不能通过p1这个变量去改变对应地址的值吗。那是不是可以通过别的变量去改变这个地址的内容呢。答案是的,如下,如果我用另外一个指针p2,同样指向数组名s,然后通过*p2 = 'i';  则可以改变const char *p1 指向的内容。

        所以说,const修饰,只是p1指向的内容不能变,并不是p1指向的那块内存的内容不能变!

 至于*(p1 + 3)为什么也不行,我也不太理解,真的只是应为使用了p1这个变量不行的吗。

指针常量:

char * const p2 = s;

指针是常量不能改变,指针指向的内容可改变。

          如果将上面代码中的常量指针,改成指针常量呢。p2[3] = 'g' 能不能正常运行。

答案是可以的,p2[3] 等价于 *(p2 +3) ;p2 +3 只是内存偏移,并没有重写回p2.所以是可以正常运行的。*p2++ 则不行,++操作会回写。

#include <stdio.h>


void constTestFunc(void)
{
	char *q = NULL;
	const char s[] = "const";
	//常量指针
	const char *p1 = s;
	char *p2 = (char *)s;
	*p2 = 'i';
	printf("p1:%c\n",*p1);
	//char const *p1 = s;
	printf("p1:%c p1 addr:%p\n", *p1, p1);
	//p1[3] = 'g';
	//*(p1+3) = 'g';
	q = (char *)(p1 + 3);
	*q = 'g';
	printf("q:%c q addr:%p\n",*q,q);


	char * const p3 = (char *)s;
	p3[3] = 'g';
	printf("p3[3] = %c\n", p3[3]);
	
	//*p3++ = 'h';//error p3 是只读的

}
int main(void)
{
	constTestFunc();
	return 0;
}

注:如有错误的地方,请大神指出和赐教!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值