1, 字符指针有初始值时,不能修改其中字符的值
#include<iostream>
using namespace std;
int main()
{
char *p1 = "nihao";//字符指针赋值给字符指针只能读不能修改字符的值
char *p2 = p1;
p1[0] = 'm';//尝试修改,会报错
return 0;
}
会报错:
原因
因为char *
字符指针,指向的数据存储在静态存储区,里面的值不允许修改。相当于const char *
表示指针指向内存区域不能修改。也就是上面的字符串nihao不能修改。
2,字符指针赋值给另外一个字符指针,接受字符串的指针也只能进行读取操作。
#include<iostream>
using namespace std;
int main()
{
char *p1 = "nihao";//字符指针赋值给字符指针只能读不能修改字符的值
char *p2 = p1;
p2[0] = 'm';//尝试修改,会报错
return 0;
}
同样报错:访问权限的问题
原因
这里原因跟上面一样,只不过将char *
赋值给另一个char *
,本质上还是尝试修改一个const char *
.也不允许修改。
3,如果想要对字符指针里面的值进行操作怎么办呢?(最简单的方法直接看4.)
- 申请动态内存(在堆中,属于动态存储区,允许修改)malloc(c)或者new(C++)
- 将静态数据区数据复制到动态内存中进行修改
看例子:
1)用C语言中strcpy
函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int main()
{
char *p1 = "nihao";
char *p2=new char[sizeof(p1)+1];//new 开辟一段新的内存,注意要加上1,要加上字符串末尾‘\0’
strcpy(p2, p1);//调用字符串copy函数,将静态内存区数据复制到动态内存中。
p2[0] = 'm';//对新开辟的内存进行操作
cout << p2<<endl;//输出操作后的结果
cout << p1<<endl;//对原来字符串没有影响,原来字符串可以看做常量,不能修改。
}
原因
为什么这里字符指针可以修改?因为char * =new
在堆中new(malloc和new一样的效果)了一块内存,该内存是动态存储区,允许修改值。
2)可以用C++中string 类解决
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a= "nihao";
string b = a;
b[2] = 'M';//将一个string a赋值给另外一个string b后,可以对b进行操作,对原来那个string a类没影响。
/*a[1] = 'M';*/
cout << b<<endl;//输出操作结果
cout << a << endl;//对原来那个string a类没影响,验证结果
}
4,直接用char []定义字符变量,允许修改某个字符
代码
char a[10] = "nimao";
a[2] = 'h';//直接修改。因为定义了一个字符数组。字符数组放在栈内存中,属于动态内存区,允许修改。
for (int i = 0; i < sizeof(a); i++)
{
cout << a[i];
}
原因
因为定义了一个字符数组char a[10]
。字符数组放在栈内存中,属于动态内存区,允许修改。
补充:
需要了解的c语言几个存储区
动态存储区
包括堆存储区、栈存储区。
- 你需要知道的是:堆一般是留给程序员用的,比如我们new一个数组,malloc数组,都是存放在堆中,用完后我们需要自己delete清理内存(虽然系统也会帮忙自动垃圾清理)。
- 定义一个数组,是放在栈储存区。栈一般是系统自己用的,像递归执行每一层执行状态都存储在栈存储区中。
静态存储区
存放常量、静态变量、全局变量
程序区
存放程序语句
参考链接
注意char * 和char []区别
char *不可以修改某个字符,char []可以修改某个字符。