字符串数组和字符串指针

字符串数组和字符串指针

标签:c/c++


  • 一个例子:

    char *getStr(){
        char str[] = "hello world";  // 生成在栈空间的局部变量
        return str;
    }

  有问题,因为 char str[] = "hello world"; 定义了一个局部字符数组(注意str是数组),保存在栈中,初始化的字符串也在栈中,函数返回的时候,会释放栈中被调用函数对应的空间,返回该临时变量的地址,返回的是一个已经释放了的空间的地址。
  解决方法:str[]改成*str即可,此时,str是在栈中,但是字符串常量是在.rodata段(常量区),释放的时候只会释放栈中的数组名,.rodata段数据的生命周期是整个函数的执行周期。


  • 数组名的常量特性以及二维数组的初始化方法

    char a[] = "hello";
    a[0] = 'H';    // success
    a = "world";   // error

      以上这样的代码会报错,因为数组只能被初始化相当于 char *const a = "hello"注意a是数组名,是一个地址常量;如果重新用一个字符串常量赋值,就会改变其指向的地址。也就是说 a 指向的地址不能改变,但 a 的内容可以改变可以用a[0]=’H’来改变a数组的值;,也可以用strcpy/memcpy进行赋值,只是对不变的地址进行内容填充。

    • 常量特性在自增方面的限制:
      指针可以自增(void指针除外,因为类型未知,自增长度未知),但是数组a不能自增,常量不可以自增。

    • 下面是数组名常量特性的一个例子:

    char a[3][5];
    a = {"asas", "dds", "as"}; // error

    【注意】是会报错的,就是因为“常量的原因”。所以二维数组的初始化方法:

    1. 声明的时候初始化

    2. 声明之后,赋值初始化,比如a[0][1] = ‘a’, 不能 a[0-3] = "asas",这种初始化方法使用的是字符串常量,赋值的时候会改变指针指向的地址,即会改变a的地址信息,不仅仅是二维的地址信息,还有二维下一维的地址也具有常量特性。

    3. strcpy/memcpy 等对a[0-3]进行初始化


  • 指向字符串常量的指针的一个问题

    • 版本 A
    char *s = "hello";
    • 版本 B
    char *s;
    s = "hello";  // valid
    s[0] = 'H';   // invalid

      虽然两个版本的赋值看起来都是用字符串常量进行赋值,但是版本 A 的那个语句叫做初始化,版本 B 才是赋值。跟A中字符串赋值不同的是:
      ”hello”中的双引号做了3件事:
      1.申请了空间(在常量区),存放了字符串,不像数组存在栈中
      2. 在字符串尾加上了’/0’
      3.返回地址
      所以,s是一个指针,指针指向地址很正常。s[0] = ‘H’;出错的原因是字符串保存在常量区!不能修改!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值