對C C 中字串的理解

2021-08-23 12:07:22 字數 2096 閱讀 5375

c/c++ 中每個字串都以字元\0作為結尾,以此作為字串結束的標誌。

為了節省記憶體,c/c++ 把常量字串放到單獨的乙個區域(一般放置在.rodata中)。當幾個指標賦值給相同的常量字串時,它們實際上會指向相同的記憶體位址,因為在記憶體中,只存在乙份相同的常量字串

.rodata區域一般用來放置唯讀資料,如常量字串,const修飾的變數等(也有的編譯器將常量字串放在.data中)

下面是一道常見的面試題(本人就遇到過),略做了修改:

int main(int argc, char *argv)
gcc 7.3.0中執行的結果為:

0x7fff49fcfbd0

0x7fff49fcfbdc

0x557768a2ebc5

0x557768a2ebc5

0x557768a2ebc5

str1 and str2 are not same.

str3 and str4 are same.

解析:str1 和 str2 是兩個字串陣列,編譯器會為它們分配兩個長度為 12 位元組的空間(在棧空間中),並把 「hello world」 的內容分別複製到陣列中去,即使 str1 和 str2 前面有const修飾,結果也是這樣,即這是兩個初始位址不同的陣列,str1 和 str2 的值當然不一樣,但是陣列裡的內容是一樣的。

**中出現的所有「hello world」在記憶體中其實只存在乙份(可通過objdump -s檢視)。編譯器將所有相同的常量字串在.rodata中只儲存其乙份實體,但是可以在程式中存在多個不同名稱的指標去指向它,但是那些指標變數裡所存的內容卻是一樣的(指標變數本身的位址不同),存的都是這個相同的常量字串中所在記憶體的位址。所以 str3 和 str4 的值是相同的。

通過objdump工具可以證實上面所述,執行objdump -s a.out命令:

...

contents of section .rodata:

0bc0 01000200 0068656c 6c6f2077 6f726c64 .....hello world

0bd0 00737472

3120616e

64207374

72322061 .str1 and str2 a

0be0 7265206e 6f742073 616d652e 00737472 re not same..str

0bf0 3320616e

64207374

72342061

72652073

3 and str4 are s

0c00 616d652e 00737472

3320616e

64207374 ame..str3 and st

0c10 72342061

7265206e 6f742073 616d652e r4 are not same.

0c20 00

...

從上面的結果可以得知,所有的常量字串都儲存在.rodata中,而且相同的常量字串只存在乙份。

常量字串的型別為const char *,是乙個字元陣列。

cout << typeid(「hello world」).name() << endl; // a12_c

cout << typeid(str3).name() << endl; // pkc

C C 中的字串

getch函式 head file include conio.h 功能 從控制台無回顯的讀取乙個字元 用法 int void getch 該函式函式經常用於互動輸入的過程中完成暫停等功能 getche函式 head file include conio.h 功能 從控制台帶回顯的讀取乙個字元 用法...

對Python中字串編碼的理解

字串,作為python中基本資料型別中的一種,也是使用最頻繁的資料型別。這裡對字串的編碼格式做乙個總結。在python中字串有兩種形式 一種是bytes型別,一種是str型別。str bytes encode編碼 bytes str decode解碼 可以使用下圖這種理解方式 1.1引數 1.2示例...

C C 對char 字串的操作

連線字串 void strcat char before,char after 複製字串 void strcpy char newstr,const char oldstr 獲取字串長度 size t getlenth const char str 轉化為小寫 void strlwr char st...