[英]What happens when I write `char str[80];`?
當我寫這篇文章時,幕后發生了什么: char str[80];
?
我注意到我現在可以設置str = "hello";
並且還str = "hello world";
之后。 第一次strlen(str)
是5
,第二次是11
;
但為什么? 我以為在str = "hello";
,索引5處的char變為null( str[5]
變為'\\0'
)。 這不是說str
的大小現在是6,我不應該將其設置為"hello world"
嗎?
如果不是,那么strlen
和sizeof
每次如何計算正確的值?
我認為您在兩個不同的概念之間感到困惑:數組的分配長度 (可用的總空間有多少)和字符串的邏輯長度 (正在使用的空間有多少)。
編寫char str[80]
,將獲得80個字符的存儲空間。 您可能最終不會使用所有的空間,但是無論您嘗試在其中存儲什么字符串,您總是將有80個插槽可以放置字符。
如果存儲字符串"hello"
到str
,然后的前六個字符str
將被設置為h
, e
, l
, l
, o
,和一個空終止符。 不過,這不會更改分配的長度 -您仍然可以使用74個其他插槽。 如果然后將其更改為"hello, world"
,那么您將使用額外的七個字符,因為您很容易分配有足夠的空間來容納東西,所以這恰好適合。 您剛剛更改了邏輯長度 ,即該空間中有多少空間用於有意義的數據,但沒有更改分配的長度 ,而是有多少可用空間。
這樣想吧。 當您說char str[80]
,您購買的是一塊80英畝的土地。 如果您隨后將"hello"
放入其中,則表示您正在使用80英畝可用土地中的6英畝。 其余的土地仍然是您的-您可以在那建造任何東西-因此,如果您決定將所有東西拆掉,並建造更長的線,占用更多的土地,那就很好。 沒有人會反對。
strlen
函數會返回字符串的邏輯長度 -您要存儲的字符串中有多少個字符。 它通過對字符進行計數直到找到指示字符串邏輯結尾的空終止符來工作。 sizeof
運算符返回分配的數組長度 ,即您有多少個插槽。 它在編譯時起作用,並不關心數組的內容是什么。
當您將變量聲明為char str [80]時,將在堆棧上分配80個字符的數組的空間。 當特定的堆棧框架超出范圍時,該內存將自動釋放。
當您將其分配給字符串文字“ hello”時,它會將每個字符復制到數組中,然后在字符串的末尾放置一個空終止符(str [5] =='\\ 0')。 字符串長度和數組大小是兩件事,這就是為什么您可以將其重新分配給“ hello world”的原因。 字符串長度就是空終止符之前有多少個連續字符。 如果改為將str聲明為char str [5],則在嘗試將其重新分配給“ hello world”時確實會導致崩潰。 查看strlen的簡單實現可能會有所幫助:
size_t strlen(const char *str)
{
size_t return_val = 0;
while (str[return_val] != '\0') return_val++;
return return_val;
}
當然,如果沒有空終止符,則上述天真的實現將崩潰。
我假設您正在使用C。當您編譯“ char str [80];”時 基本上為您分配了80個字符的空格。 sizeof(str)應該始終告訴您這是一個80字節長的內存塊。 strlen(str)將計算從str [0]開始的非零字符。 這就是為什么“ Hello”為5和“ Hello world”的原因。
我建議您學習使用strnlen,strncpy,strncmp,snprintf等函數,這樣可以防止在數組末尾進行讀/寫操作,例如:strnlen(str,sizeof(str))。
另外,您還可以開始閱讀在線教程,並找到一本入門的C / C ++書。
當您聲明類似char str[80];
的數組時char str[80];
在堆棧上為您保留了80個char
,但它們沒有初始化-它們獲得了當時內存中已存在的任何內容。 作為程序員,您要初始化數組。
strlen
遵循以下原則進行操作:
int strlen(char *s)
{
int len = 0;
while(*s++) len++;
return len;
}
換句話說,它返回一個空終止字符串的長度的字符數組,即使長度小於整個陣列的大小。
sizeof
返回類型或表達式的大小。 如果陣列是80 char
悠久和char
是一個字節長,它會返回80,即使沒有一個數組中的值都被初始化。 如果您有一個由5個int
的數組,並且一個int
長為4個字節,則sizeof
將產生20。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.