更改const char*的值更改的是什么?

文中参考并引用了的地址:
1.为什么const char * 的内容是可以更改的?-CSDN论坛
2.cout输出char *类型指针地址_foroverontheroad的博客-CSDN博客

回顾C的知识的时候发现C是没有严格意义上的字符串类型的,使用一个(char*)指针指向首字符的地址来实现字符串的定义和读取。

然后发现使用的时候const char*都是带const,很少见(几乎见不到)char*,所以提出了疑问,这里的const使该指针成为了常量指针,与不加const有什么影响吗?

先说结论,在有的编译器里没有影响,编译器会提示有问题(Conversion from string literal to 'char *' is deprecated),但是两者使用没有区别,因为后面定义的字符串必定是常量,也就是说不可更改值的。

但是为什么const char*定义字符串后还可以更改字符串呢?

先说结论,字符串并没有被更改,而是指针指向的地址改变了,重新申请了一块内存存储新的字符串,结论来自参考CSDN社区:为什么const char * 的内容是可以更改的?

但是很想知道发生了什么,所以做了如下实验:

#include <iostream>
using namespace std;

int main()
{
    const char *a = "abcde";
    cout<<"a = \t"<<a<<endl;
    cout<<"*a = \t"<<*a<<endl;
    cout<<"&(*a) = \t"<<&(*a)<<endl;


    return 0;
}

输出结果如下:

按道理说,a是一个指针,a输出的是a指向的地址,然后*a是a指向的地址的值,但是由于这里比较特别,a是char*,输出a不会输出地址,哪怕&(*a)和&(*a[0])都不会输出地址,而是字符串。想要知道a指向的地址只能对强制转换a的类型,如int*,方法来源于这篇博客cout输出char *类型指针地址

下面的测试思路是,改变字符串内容,看是什么被改变了,然后在改变后尝试着通过记录原字符串的地址去得到原来的字符串。这里借用了一个int指针暂存原字符串的首地址

#include <iostream>
using namespace std;

int main()
{
    const char *a = "abcde";
    cout<<"a = \t"<<a<<endl;
    cout<<"更改前a所在的地址 = \t"<<&a<<endl;
    cout<<"更改前a指向的地址 = \t"<<(int*)a<<endl;
    int* temp = (int*)a;   //利用一个int指针暂时存储字符串首地址

    cout<<"---------------------------";
    a = "fgh";
    cout<<"\na = \t"<<a<<endl;
    cout<<"更改前a所在的地址 = \t"<<&a<<endl;
    cout<<"更改后a指向的地址 = \t"<<(int*)a<<endl;

    cout<<"---------------------------";
    cout<<"\n更改后收寻原字符串的数据\n";
    char* p = (char*)temp;  //利用字符串首地址找回原始字符串数据
    for(int i=0; i<5; i++)
    {
        cout<<*p;
        p++;
    }
    cout<<endl;

    return 0;
}

输出结果:

可以看到,实际就是a指向的地址变了,原地址的值是没有发生更改的,之后还利用指针找到了原来的值。 

const char *a,a是常量指针,指针的指向可以改变,指针指向的值不能改变,并没有违背这个规则。如果这里使用char* const a(const char* const a),本来作为字符串就是一个常量,这下又是指针常量,指针的指向也不可以更改了,那么,a算是锁死了,啥也变不了了。

无论const char *a还是char *a,都是一个常量指针,所以a[1] = 'x'是错误的,因为值不可改变,但是作为整个字符串的指针可以指向另一个地址即可。


10月30日补充

c++的STL库是有字符串string的模板的。使用string是可以替代c中的字符串的。但是两者是不同的。

1. string字符串可读可改,并不是常量,char*字符串如上所说,只读不能更改。
2. string字符串可以由char*字符串构造或者赋值,生成的string字符串同样可读可改。

#include <iostream>
using namespace std;

void test01()
{
    string str1 = "hello world";
    const char* temp = "hello world";
    string str2 = temp;


    //字符修改
    str1[0] = 'x';
//    temp[0] = 'x';  //非法,temp是字符串常量
    str2[0] = 'x';

    cout << str1 << endl;
    cout << str2 << endl;

}

int main() {

    test01();

    return 0;
}

str1和str2都可更改,但是temp不能更改,哪怕是char* temp = "hello world";没有加const依旧是常量,不能更改的。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值