簡體   English   中英

關於C中的數組和字符串的困惑

[英]Confusion About Array and String in C

S1S2S3什么區別?

char S1[6];
S1[0] = 'A';
S1[1] = 'r';
S1[2] = 'r';
S1[3] = 'a';
S1[4] = 'y';

char S2[6] = {'A','r','r','a','y'};

string S3 = "Array";

當我使用if (strcmp(a,b) == 0)運行程序時,其中a, b = S1, S2, S3 它表明S2S3是相同的, S1S2是不同的。 這是為什么? 為什么不是這三個都是等價的?

當我將'\\0'加回到S1bS1c 所有3都是一樣的。 這是可以理解的。

但為什么在我的第一次試驗中, S2S3是相同的? 我也沒有包含'\\0' 我懷疑S1S2應該是相同的,但不是S2S3

誰能告訴我為什么我的想法是錯的???

謝謝你的回答。 我已嘗試將設置更改為以下內容:

char S1[5];
S1[0] = 'A';
S1[1] = 'r';
S1[2] = 'r';
S1[3] = 'a';
S1[4] = 'y';

char S2[5] = {'A','r','r','a','y'};

string S3 = "Array";

現在顯然S2S3不一樣,因為它們的差異為'\\0' 但是,如果我使用strcmp來比較兩者,那么為什么S1S2再次不一樣,我仍然有點困惑?

比較數組的實際內存中值:

  1. S1是6個元素大,但你只指定0-5的值,第6個元素沒有顯式設置,所以它保留了內存位置在分配之前的任何值。
  2. S2類似於S1,僅提供5個元素,但是當使用{,}語法時,任何額外元素都歸零。 所以char foo[5] = { 1, 2 }char foo[5] = { 1, 2, 0, 0, 0} char foo[5] = { 1, 2 }相同。
  3. S3使用字符串語法初始化數組,創建一個char (或wchar_t )數組,其中一個額外的元素設置為\\0 (空終止符)。

視覺:

S1 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x??
S2 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x00
S3 = 0x41, 0x72, 0x72, 0x61, 0x79, 0x00

請注意,您遇到了strcmp的安全問題:它沒有長度參數,它會一直搜索,直到遇到\\0 ,這可能永遠不會(即直到它導致段錯誤或訪問沖突)。 而是使用更安全的函數,如strncmp或(如果使用C ++) std::string類型。

It shows that S2 and S3 are the same, and S1 and S2 is different.

S3包含S1沒有的nul終結符。 這個string S3 = "Array"; 手段

| A | r | r | a | y | \0 |

雖然S2是

| A | r | r | a | y | \0 |

雖然S1是

| A | r | r | a | y | Garbage |

S1和S2比較可以導致UB(我推測),因為S1不是nul終止的,並且沒有我們在strcmp傳遞的長度。

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char S1[6];
    S1[0] = 'A';
    S1[1] = 'r';
    S1[2] = 'r';
    S1[3] = 'a';
    S1[4] = 'y';
    S1[5] = 0;

    char S2[6] = {'A','r','r','a','y', 0};
    printf("%d" ,strcmp(S1,S2));
    return 0;
}

輸出:

0

strcmp()函數開始比較每個字符串的第一個字符。 如果它們彼此相等,則繼續使用以下對,直到字符不同或直到達到終止空字符。

我不認為使用它來比較S1和S2是安全的。 輸入到strcmp是第一個字符的地址。 S1不是以空值終止的。 雖然在兩種情況下都分配了6個字節,但S1 [5]未初始化。 有可能他們有一些垃圾價值。 這里的風險是strcmp最終還會在搜索字符diff或null字符時比較未分配的內存。 這甚至可能導致seg故障或訪問沖突。

可視化S1,S2,S3的內存對齊可能是這樣的

S1 = A | r | r | a | y | ?
S2 = A | r | r | a | y | 0
S3 = A | r | r | a | y | 0

S2和S3之間的任何比較都是安全的。 S1 vs S2或S3可能不是。

只需添加現有答案

char S2[6] = {'A','r','r','a','y'};

string S3 = "Array";

兩者都是NULL終止,因此strcmp()運行良好,並說它們都是相同的。 而對於S1 ,分配是明確完成的,此陣列沒有NULL終止。 所以這不是C中的有效字符串。因此使用strcmp()可能會導致未定義的行為。

S3的要點是S3是一個只讀的字符串文字。 大多數情況下,這些值存儲在只讀位置。 因此,當您在初始化后嘗試向S3寫入內容時,您可能會看到崩潰。所以我們應該在使用S3分配時牢記這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM