关于指向常量的指针(const int*)的疑问

brk1985 2011-07-08 09:30:36

#include <iostream>
//#include "string.h"

using namespace std;

void main()
{
//char* test1 = test("abcd");
const int i = 1;
int j = 10;
int k = 20;
const int* a = &j;//a指向j;a可变,a指向的对象不可变
cout << "a1=" << *a << endl;
a= &k;//①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
cout << "a2=" << *a << endl;
k=5;//②此时a指向k,不是说a指向的对象不可变吗???
//*a=5;//③a指向的对象值不可变,编译出错,*a不就是k吗???
cout << "a3=" << *a << endl;

}


①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
②此时a指向k,不是说a指向的对象不可变吗???
③a指向的对象值不可变,编译出错,*a不就是k吗???
...全文
213 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
brk1985 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 my_live_123 的回复:]

特此,为了总结了一下!希望对你有用!http://blog.csdn.net/my_live_123/article/details/6595873

C/C++ code

#include <iostream>

using namespace std;

int main()
{
const int i = 1;
int j = 10;
int k = 20;……
[/Quote]

总结的很有学习意义,对我有帮助,O(∩_∩)O
brk1985 2011-07-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 my_live_123 的回复:]

特此,为了总结了一下!希望对你有用!http://blog.csdn.net/my_live_123/article/details/6595873

C/C++ code

#include <iostream>

using namespace std;

int main()
{
const int i = 1;
int j = 10;
int k = 20;……
[/Quote]

然后看后面的内容是*p1,那么p1就是一个指向“常量”的
一个整型指针。(注意引号的意义)=============================这句很受益,我题目的说法应该也有点问题,应该是我对“const int*”这句含义理解出错了,题目上的这个常量还是得打引号的,因为这个“常量”与通常所说的const常量不一样,该“常量”只是相对指针来讲是常量,无法用*p1修改值,未必一定是通常所说的const常量。。。
一根烂笔头 2011-07-10
  • 打赏
  • 举报
回复
特此,为了总结了一下!希望对你有用!http://blog.csdn.net/my_live_123/article/details/6595873


#include <iostream>

using namespace std;

int main()
{
const int i = 1;
int j = 10;
int k = 20;
const int * a = &j;//a指向j;a可变,a指向的对象不可变
cout << "a1=" << *a << endl;
a= &k; //①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
cout << "a2=" << *a << endl;
k=5; //②此时a指向k,不是说a指向的对象不可变吗???
//*a=5;//③a指向的对象值不可变,编译出错,*a不就是k吗???
cout << "a3=" << *a << endl;

}
/*
这些是楼上的不错的回答(回答的楼主,就不注明了)

/////////////////////////////////
①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
当然可以,不过用a还是改不了值。a被声明为const char *,编译器会做判断。
②此时a指向k,不是说a指向的对象不可变吗???
可以用k改,但不能用a改
③a指向的对象值不可变,编译出错,*a不就是k吗???
同上。

//////////////////////////////////
首先const是依靠编译器来实现的,并非说他修饰的变量或者对象在内存就一定要放在
常量区。所以这也是为什么我们一旦在代码中有修改该变量或者对象的时候就会编译错
误,而不是说运行的时候报错。

你常量指针a指向一个非常量这个是完全合理的。当你这么做的时候意味着你不能通过
该指针来修改它所指的对象,但是并不是说你不能直接修改该对象。这也就是为什么
你可以直接给k赋值来修改它。

/////////////////////////////////
const int* a
*a是常量,不能通过*a=xxx来赋值 a本身是可以改变,即可以修改所指向的内存地址,
但不能修改指向对象的值 但k自己改变值是k自己的事情 和a无关 a只是不能修改k的值
而已

/////////////////////////////////
const int * p1;
int * const p2;
const int * const p2;
三者是不一样的,指向常量,常量地指向,常量地指向常量

*/

/*解析我的“就近原则”,来辨别const与*的相关问题

A:const int * p1;
B: int const * p1;
C: int * const p2;
D: const int * const p2;
E:int const * const p2;
F: const 函数(超出这里要探讨的范围,不解析,只是提名一下)

A:const int * p1;
const和int就近,那么const修饰的就是一个int数据,换言之,这个int数据将被用作
常量,而不论他本身是不是常量。然后看后面的内容是*p1,那么p1就是一个指向“常量”的
一个整型指针。(注意引号的意义)

如何应用呢?
当给这个指针p1一个地址之后,当然这个地址肯定是一个整型变量的的地址(注意这里
并没有强调这个整型变量是一个常量),如果这个整型变量不是常量,可以通过原变量本
身修改其值,而不能通过指针来修改其值;如果是常量,那么甭想修改了。
另外,由于const修饰的只是int,而没有影响到p1,那么p1依旧是一个变量,可以
根据需要改变其指向。

优点:
当需要访问一个变量的时候,为了避免对其值修改的可能,就是通过这样的用法实现
即:只能访问,不能修改。“只能看,不能摸”——你懂得!

int main()
{
const int i = 1;
int j = 10;
const int * a = &j;//a指向j,j不是常量
cout << "a1=" << *a << endl;

//*a=20;//非法
j=20;//可以绕个圈,通过j本身修改,来达到*a的变值。
cout << "a1=" << *a << endl;

a=&i;//修改指向,由于i本身就是const,那么i值一定不会变
cout << "a1=" << *a << endl;
return 0;
}*/
/*
B: int const * p1;
const 和*接近!修饰整个*p1,又由于*p1本身就等价于一个整型变量,因此它和A等价
*/

/*
C: int * const p2;
const和p2就近,那么const修饰p2。即:p2是一个常指针。一旦赋值,不可改变。“一次定
终身那!”,指向只能“嫁鸡随鸡嫁狗随狗”了。无论鸡狗如何,也只能凑合,用一句台词
“凑合过吧,还能离咋滴?!”说实话:这里离的权利都没有,除非销毁指针!
同样,它指向可以是变量也可以是常量!不过这里可以通过指针修改指向变量的值,
如果它指向的是一个变量而不是常量的话!
优点:
有其本质决定。即:需要一个不改变指向的指针。当一名看家狗!十分敬业!
int main()
{
const int i = 1;
int j = 10;
int * const a= &j ;//a指向j,j不是常量
//注意这里不能通过先声明后赋值的方法。a有且仅有一次赋值机会,而且和声明同步
cout << "a1=" << *a << endl;

*a=20;//合法
cout << "a1=" << *a << endl;

j=30;//也可以绕个圈,通过j本身修改,来达到*a的变值。
cout << "a1=" << *a << endl;

//a=&i;//非法
return 0;
}
*/
/*
D: const int * const p2;
const int 和AB一致,* const p2和C一致。因此这就是ABC的“变异体”,或者说“结合体”
因此它会拥有ABC的所有特性与优点。说白了,就是杂交品种,比较优良!
还是下个定义吧:它是一个指向整型“常量”的整型常指针!

同理E:int const * const p2;也就和D等价

int main()
{
const int i = 1;
int j = 10;
const int * const a= &j ;//a指向j,j不是常量
//注意这里不能通过先声明后赋值的方法。a有且仅有一次赋值机会,而且和声明同步
cout << "a1=" << *a << endl;

//*a=20;//非法

j=30;//依旧可以绕个圈,通过j本身修改,来达到*a的变值。
cout << "a1=" << *a << endl;

//a=&i;//非法
return 0;
}
*/

一根烂笔头 2011-07-10
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 sheila_1988 的回复:]
不知道可不可以这样理解呢..
const int* a
忽略int,即const ×a,a是一个指针,×a是指a指向的地址上的数值,所以说数值不能变
另外有一个是 int* const a
则可以看成是const a,a是一个指针,指向的是一个地址,所以就是a指向的地址不能变

以前老是搞错,这样写以后就不会搞错了- -不知道原理是不是错的。。。
[/Quote]

采用“就近原则”!看const和谁近就可以辨别!
一根烂笔头 2011-07-10
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 motzyd 的回复:]
const int * p1;
int * const p2;
const int * const p2;
三者是不一样的,指向常量,常量地指向,常量地指向常量
[/Quote]
const int * p1;

int const * p1;
一样
与int * const p2;
const int * const p2;
不一样





const int* a = &j;//a指向j;a可变,a指向的对象不可变

换成

int* const a = &j;//a指向j;a可变,a指向的对象不可变

你就无法进行下面对a 的重新赋值了!
motzyd 2011-07-10
  • 打赏
  • 举报
回复
const int * p1;
int * const p2;
const int * const p2;
三者是不一样的,指向常量,常量地指向,常量地指向常量
Xomic 2011-07-10
  • 打赏
  • 举报
回复
7 楼 11楼 看懂就ok!学习......
5t4rk 2011-07-08
  • 打赏
  • 举报
回复
只需记住两点

指针常量就是指针的值是一个常量//注意指针的值不可以更改啊 其实就是地址

而常量指针则是指针指向的是一个常量//可以更改指针的值,但是不能通过指针改变所指向的变量值

//但是所指向的那个变量是可以修改的

不知楼主是否明白啊??
呵呵
zhengyuning 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 brk1985 的回复:]

引用 1 楼 luciferisnotsatan 的回复:

①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
当然可以,不过用a还是改不了值。a被声明为const char *,编译器会做判断。
②此时a指向k,不是说a指向的对象不可变吗???
可以用k改,但不能用a改
③a指向的对象值不可变,编译出错,*a不就是k吗???
同上。


“当然可以”这句能否讲的具……
[/Quote]
LZ,你可以细细品味一下11楼同学的回答。
我再说白话一点就是:const int* a = &k; //这句代码的作用是叫 *a有对k的只读权限,而无法修改。可以保证你程序的安全性。
*a = 20; //没错,他指向的是常量。
a = &j;//这句代码,同样使得 *a有对k的只读权限,而无法修改。
*a = 10; //没错,他指向的常量变成了10. 注意,他不是用*a修改的。
以上,不知我解释的是否清楚。
建议楼主,不要死记硬背一些C++的语法,需要体会何时何地去用,这样你才不会用错。这里就是使用只读的作用。可以查看 msdn strcmp等函数的参数,就是为只读的。 strcmp( const char *string1, const char *string2 );
顺便说一下,const char *string1 等效于 char const *string1
赵4老师 2011-07-08
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编并单步执行。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编并单步执行。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!
QQIANQQ 2011-07-08
  • 打赏
  • 举报
回复

const int* a = &j;//定义成const int *a 就是你不能通过改变a改变其指向的值![
Jxiaoshen 2011-07-08
  • 打赏
  • 举报
回复
const int* a
*a是常量,不能通过*a=xxx来赋值 a本身是可以改变,即可以修改所指向的内存地址,但不能修改指向对象的值 但k自己改变值是k自己的事情 和a无关 a只是不能修改k的值而已
ljq550000 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 q191201771 的回复:]

void main()
{
//char* test1 = test("abcd");
const int i = 1;
int j = 10;
int k = 20;
const int* a = &j;//a指向j;a可变,a指向的对象不可变
cout << "a1=" << *a << endl;
a= &a……
[/Quote]

顶下
ljq550000 2011-07-08
  • 打赏
  • 举报
回复
经典问题
就想叫yoko 2011-07-08
  • 打赏
  • 举报
回复
void main()
{
//char* test1 = test("abcd");
const int i = 1;
int j = 10;
int k = 20;
const int* a = &j;//a指向j;a可变,a指向的对象不可变
cout << "a1=" << *a << endl;
a= &k;//①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
-----一句话, 不可以修改*a的值, 即不可以通过a来修改j的值, 但是a可以变, 即可以指向其他位置
cout << "a2=" << *a << endl;
k=5;//②此时a指向k,不是说a指向的对象不可变吗???
-----k想怎么变就怎么变, 因为现在是通过k来修改k
//*a=5;//③a指向的对象值不可变,编译出错,*a不就是k吗???
-----一句话, 不可以修改*a的值, 即不可以通过a来修改k的值, 但是a可以变, 即可以指向其他位置
cout << "a3=" << *a << endl;

}
pengzhixi 2011-07-08
  • 打赏
  • 举报
回复
首先const是依靠编译器来实现的,并非说他修饰的变量或者对象在内存就一定要放在常量区。所以这也是为什么我们一旦在代码中有修改该变量或者对象的时候就会编译错误,而不是说运行的时候报错。

你常量指针a指向一个非常量这个是完全合理的。当你这么做的时候意味着你不能通过该指针来修改它所指的对象,但是并不是说你不能直接修改该对象。这也就是为什么你可以直接给k赋值来修改它。
brk1985 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luciferisnotsatan 的回复:]

①a指向变量k,a指向的不是常量吗,怎么非常量也可以???
当然可以,不过用a还是改不了值。a被声明为const char *,编译器会做判断。
②此时a指向k,不是说a指向的对象不可变吗???
可以用k改,但不能用a改
③a指向的对象值不可变,编译出错,*a不就是k吗???
同上。
[/Quote]

“当然可以”这句能否讲的具体点,从指向常量的指针看,k必须是常量呀?②、③理解了,不是引用,所以*a发生变化,不会引起k的变化。
brk1985 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 babilife 的回复:]

const int* a
记住这种情况是,指针指向的内容不可以改变,但指针本身的地址是可以被改变的
所以
a= &k;//地址被改变了 可以
k=5;//K是个变量,和上边没啥关系
[/Quote]

a= &k;k=5;指针指向的内容是k吧?k是变量,当然可以改变,怎么“指针指向的内容又可以改变了”?
但是从程序上看*a与k不一样?不理解这点。。。
动感超哥 2011-07-08
  • 打赏
  • 举报
回复
const int *a 指向的值可以不是常量 编译器默认是const 可以通过指针进行修改吧。。
至善者善之敌 2011-07-08
  • 打赏
  • 举报
回复
const int* a
记住这种情况是,指针指向的内容不可以改变,但指针本身的地址是可以被改变的
所以
a= &k;//地址被改变了 可以
k=5;//K是个变量,和上边没啥关系
加载更多回复(8)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧