字符串數組和字符串指針

字符串數組和字符串指針

標籤: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’;出錯的原因是字符串保存在常量區!不能修改!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章