少扯淡没用的,直接上代码
int main(int argc, char *argv[])
{
char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
printf("%s,%s",p,a);
}
这谁都能看明白,最终输出两次abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm,没问题
把代码再改改
int main(int argc, char *argv[])
{
char p[74] = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
char *a = "abcefghijkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm";
p[8]= 'd';
a[8] = 'd';
//printf("%s,%s",p,a);
}
运行,报错

错误指向了a[8] = ‘d'

错误指向第12行,为嘛尼?
看汇编

可以看到变量p,和a 都是采用了同样的方式
d使用了
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
将字符串的偏移地址,赋值到esi寄存器
a使用了
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
将字符串的偏移地址,赋值到a变量所在地址
仔细看图 这两句对字符串的取址操作,来源都是一个地方,01007500h,也就是程序数据段在内存中的位置

既然两个操作都是对同一个字符串的操作,为什么有的可以修改,有的不行?
这里面有个关于编译文件后程序的存储问题,如上例
变量a,p他们都是操作相同的字符串,两个字符串完全相同,所以,程序编译后,生成的文件内,完全没有必要保存两个相同的内容,只保留一个便可以,所以,你的程序,不管多少次使用这个字符串,实际上都是从一个地方引用的,这就是,这两句代码
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
的意思。
但这就出现了一个问题,如果两个或者多个变量都用了同一个字符串,然后最终要的,还进行了修改,结果就是,所有引用这个字符串的变量,都变了,所以
a[8] = 'd';
要直接修改数据段,就报错了
但是p可以,为什么,应为数组的处理是不一样的,看代码
mov esi,offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"... (0977588h)
lea edi,[p]
rep movs dword ptr es:[edi],dword ptr [esi]
首先,把字符串的地址给了esi,然后把p地址给了edi,
然后,通过rep movs 循环执行,吧[esi]处的字符,赋值给[edi],也就是把字符串复制一份到p
所以,你操作的
p[8] ='d';
实事上是操作了一个新的字符串,不是数据段中的那个字符串,
再看关于a的操作
mov dword ptr [a],offset string "abcefghijkmmmmmmmmmmmmmmmmmmmmmm"...
mov eax,1
shl eax,3
mov ecx,dword ptr [a]
mov byte ptr [ecx+eax],64h
首先把1给了eax,然后执行位移3,把EAX,变成8,把a的地址,也就是字符串的地址给了ecx,然后吧64h也就是d,赋值给[ecx+eax] 那个位置,也就是j的位置,因而你操作的是数据段中的那个字符串,就是上面的原因,系统会阻止你修改数据段,因而报错
到此这篇关于C++中char[]能修改char*却不行的文章就介绍到这了,更多相关C++ char*不能修改内容请搜索html5模板网以前的文章希望大家以后多多支持html5模板网!
浅谈C++ 设计模式的基本原则这篇文章主要介绍了++ 设计模式的基本原则,主要的目标是实现最终目的,高内聚,低耦合,开放封闭原则类的改动
C++基于OpenCV实现手势识别的源码这篇文章主要介绍了C++基于OpenCV手势识别的实现源码,这里用到背景减法模型知识,具体实例代码跟随小编一起看看吧
一道面试题教你轻松玩转C++指针下面小编就为大家带来一篇深入理解c++指针的指针和指针的引用。小编觉得挺不错的,现在就分享给大家,也给大家
一篇文章带你入门C++的异常处理C++ 提供了异常机制,让我们能够捕获运行时错误,本文就详细的介绍了C++异常处理入门,具有一定的参考价值,感兴
C++内存模型和名称空间详解这篇文章主要给大家介绍了关于C/C++中的内存模型和名称空间详解,文中通过示例代码介绍的非常详细,对大家学习或
利用c++写一个简单的推箱子小游戏推箱子想必是很多人童年时期的经典游戏,我们依旧能记得抱个老人机娱乐的场景,下面这篇文章主要给大家介绍了关于