簡體   English   中英

C編程 - strlen的功能

[英]C Programming - Functionality of strlen

我正在嘗試理解一些字符串函數,以便我可以在以后的編碼項目中更有效地使用它們,所以我在下面設置了簡單的程序:

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

int main (void)
{
// Declare variables:
char test_string[5];
char test_string2[] = { 'G', 'O', '_', 'T', 'E', 'S', 'T'};
int init; 
int length = 0;
int match;

// Initialize array:
for (init = 0; init < strlen(test_string); init++)
{    test_string[init] = '\0';
}

// Fill array:
test_string[0] = 'T';
test_string[1] = 'E';
test_string[2] = 'S';
test_string[3] = 'T';

// Get Length:
length = strlen(test_string);

// Get number of characters from string 1 in string 2:
match = strspn(test_string, test_string2);

printf("\nstrlen return = %d", length);
printf("\nstrspn return = %d\n\n", match);

return 0;
}

我希望看到回歸:

strlen return = 4 strspn return = 4

但是,我看到strlen return = 6和strspn return = 4.據我所知,char test_string [5]應該分配5個字節的內存並將十六進制00放入第五個字節。 for循環(甚至不應該是nessecary)然后應該將test_string的所有內存字節設置為十六進制00.然后,緊接着的行應該填充test_string字節1到4(或test_string [0]到test_string [3])用我指定的。 此時調用strlen應該返回一個4,因為它應該從字符串0的地址開始並計算一個增量,直到它到達第一個空字符,即字符串[4]。 然后strlen返回6.任何人都可以解釋這個嗎? 謝謝!

char test_string[5];

test_string是一個包含5個未初始化的 char對象的數組。

for (init = 0; init < strlen(test_string); init++)

KABOOM。 strlen掃描第一個'\\0' 0'null字符。 由於test_string的內容是垃圾,因此行為未定義。 如果碰巧test_string字符,它可能返回一個小值,如果test_string沒有任何零字節,它可能返回一個大值或程序崩潰。

即使不是這種情況,在for循環的標題中評估strlen()也是低效的。 每個strlen()調用都必須重新掃描整個字符串(假設你給它一個有效的字符串),所以如果你的循環工作,它將是O(N 2 )。

如果希望test_string只包含零個字節,可以這樣初始化它:

char test_string[5] = "";

或者,因為您稍后初始化前4個字節:

char test_string[5] = "TEST";

要不就:

char test_string[] = "TEST";

(后者讓編譯器發現它需要5個字節。)

回到你的聲明:

char test_string2[] = { 'G', 'O', '_', 'T', 'E', 'S', 'T'};

這導致test_string2長7個字節, 沒有尾隨'\\0'字符。 這意味着將test_string2傳遞給任何需要指向字符串的指針的函數都會導致未定義的行為。 你可能想要這樣的東西:

char test_string2[] = "GO_TEST";

strlen搜索'\\ 0'字符來計算它們,在你的test_string中沒有,所以它會繼續,直到它找到一個恰好距離數組開頭6個字節的字符,因為它是未初始化的。

編譯器不會生成用於初始化數組的代碼,因此如果稍后填寫該代碼,則無需付費即可運行該代碼。

要將其初始化為0並跳過循環,您可以使用

char test_string[5] = {0};

這樣,所有字符都將初始化為0,並且在您使用“TEST”填充數組后,您的strlen將起作用。

這里有一些問題。 首先, char test_string[5]; 只需為該字符串留出5個字節,但不將字節設置為任何字節。 特別是,當你說“char test_string [5]應該分配5個字節的內存並將十六進制00放入第五個字節 ”時,第二部分是錯誤的。

其次,你的數組初始化循環使用strlen(test_string)但由於strlen(test_string)的字節未初始化,因此無法知道是什么,因此strlen(test_string)返回一些未定義的結果。 清除數組的更好方法是memset( test_string, 0, sizeof(test_string) );

使用“TEST”填充數組但不在末尾設置NULL字節,因此最后一個字節仍未初始化。 如果你執行上面的memset,這將被修復,或者你可以手動執行test_string[4] = '\\0'

暫無
暫無

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

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