关于指针和数组的问题

yiruirui0507 2010-03-08 10:43:44
#include<iostream>
using namespace std;
void main()
{
char a[] = "hello";
a[0] = 'x';
cout << a << endl;
char *p = "world";
p[0] = 'x';
cout << p << endl;
}
为什么运行会出错呢,请大家帮忙分析分析!
...全文
123 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2010-03-09
  • 打赏
  • 举报
回复
单步调试和设断点调试是程序员必须掌握的技能之一。

VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。

想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
某某9 2010-03-09
  • 打赏
  • 举报
回复
引用 7 楼 coding_hello 的回复:
周经贴。。。每周都会有人问。。。唉

char *p = "world";
这里的"world"字符串是属于一块readonly属性的内存块,所以p[0]赋值必然失败,因为是readonly.

char a[] = "hello";
这样成功是因为这一行实际上是这样的:
char a[6];
strcpy(a, "hello");
所以a[0] = 'x'是对堆栈上的一个内存地址操作,而堆栈的内存块属性是readwrite
char *p = "world";
这里的"world"字符串是属于一块readonly属性的内存块,所以p[0]赋值必然失败,因为是readonly.

char a[] = "hello";
这样成功是因为这一行实际上是这样的:
char a[6];
strcpy(a, "hello");
所以a[0] = 'x'是对堆栈上的一个内存地址操作,而堆栈的内存块属性是readwrite
tianma2005123 2010-03-09
  • 打赏
  • 举报
回复
1L的同志已经说了。
ithiker 2010-03-09
  • 打赏
  • 举报
回复
学习了...............
na2650945 2010-03-09
  • 打赏
  • 举报
回复

char *p = "world";
p[0] = 'x';

因为p指向的是常量字符串。
值不能改变的。
cq_gongyoulong 2010-03-09
  • 打赏
  • 举报
回复
引用 7 楼 coding_hello 的回复:
周经贴。。。每周都会有人问。。。唉

char *p = "world";
这里的"world"字符串是属于一块readonly属性的内存块,所以p[0]赋值必然失败,因为是readonly.

char a[] = "hello";
这样成功是因为这一行实际上是这样的:
char a[6];
strcpy(a, "hello");
所以a[0] = 'x'是对堆栈上的一个内存地址操作,而堆栈的内存块属性是readwrite




这个讲得很形象了,每次我只是记得要这样做,但不知道为什么!
Julykey 2010-03-09
  • 打赏
  • 举报
回复
貌似我经常看到13楼说那句话。。。
kuillldan 2010-03-09
  • 打赏
  • 举报
回复
#include <iostream> 
using namespace std;
void main()
{
char a[] = "hello";
a[0] = 'x';
cout << a << endl;
char *p = "world";
/*限定词c o n s t是很严格的,const没被强调的地方是有关串字面值。也许有人写:
char* cp="world";
编译器将接受它而不报告错误。从技术上讲,这是一个错误,因为串字面值(这里是
“world”)是被编译器作为一个常量串建立的,所引用串的结果是它在内存里的首地址。
所以串字面值实际上是常量串。然而,编译器把它们作为非常量看待,这是因为有许多现
有的C代码是这样做的。当然,改变串字面值的做法还未被定义,虽然可能在很多机器上是这
样做的。
如果想修改字符串,就要把它放到一个数组中:
char p[] = "world";
*/
p[0] = 'x';
cout << p << endl;
}
野男孩 2010-03-09
  • 打赏
  • 举报
回复
周经贴。。。每周都会有人问。。。唉

char *p = "world";
这里的"world"字符串是属于一块readonly属性的内存块,所以p[0]赋值必然失败,因为是readonly.

char a[] = "hello";
这样成功是因为这一行实际上是这样的:
char a[6];
strcpy(a, "hello");
所以a[0] = 'x'是对堆栈上的一个内存地址操作,而堆栈的内存块属性是readwrite
yiruirui0507 2010-03-09
  • 打赏
  • 举报
回复
谢谢各位大虾热情的帮助!
wilddj 2010-03-09
  • 打赏
  • 举报
回复
正在学习中,受益了:)
starcat 2010-03-08
  • 打赏
  • 举报
回复
又是这个问题,老谭教材再版该补充说明一下了
cismylife 2010-03-08
  • 打赏
  • 举报
回复
我记得是编译器的优化功能,把"hello"从常量区移到了栈区,楼主可以用过去地址来看看地址验证一下
yyg990441 2010-03-08
  • 打赏
  • 举报
回复
char a[] = "hello";//说明a这个数组有6个元素为:'h''e''l''l''o''\0'
请注意,这6个元素都是a数组里面的元素,a数组当然可以修改它们.

char *p = "world";
相当于(只是说明,伪代码,真的这么写会有问题)
const char vec[]="world";//const说明这个数组的元素是不可以改变的
char*p = vec;//注意,这里数组并不是是属于p,平时个指针,指到数组vec中想修改它的元素.但数组vec的元素是const的不然修改,所以报错
yiruirui0507 2010-03-08
  • 打赏
  • 举报
回复
能分析具体点吗?我还是想不太明白,比较笨的那种人!谢谢!
stardust20 2010-03-08
  • 打赏
  • 举报
回复
或者动态分配内存。。像这样
#include <iostream> 
using namespace std;
void main()
{
char a[] = "hello";
a[0] = 'x';
cout << a << endl;
char *p;
p=new char[10];//动态分配空间
strcpy(p,"world");
p[0] = 'x';
cout << p << endl;
delete[] p;
}
stardust20 2010-03-08
  • 打赏
  • 举报
回复
char *p = "world";
"world"存在常量区。。你不能修改它p[0]= 'x'; 就出错了。。
你改成char p[]="world";就可以了

64,637

社区成员

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

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