【C】字串,字元和位元組(C與指標第9章)

來源:互聯網
上載者:User

標籤:style   blog   http   io   使用   ar   檔案   資料   sp   

C語言沒有一種顯式的資料類型是字串的。

C語言儲存字串:字串常量(不能修改);字元數組或動態分配的記憶體(可以修改)


****************************************************

9.1 字串基礎

字串概念:字串是以一個位元模式為全0的NUL位元組結尾的0個或多個字元

NUL位元組是終止符,字串的長度不包含NUL位元組

標頭檔string.h包含了使用字串函數所需的原型和聲明(可以在linux中查看,有很多函式宣告)。


****************************************************

9.2 字串長度

size_t是一個不帶正負號的整數類型。定義與stddef.h標頭檔

做算術運算的時候不帶正負號的整數可能導致不可預料的結果(想想,見9.2)


****************************************************

9.3 不受限制的字串函數

——》複製字串 strcpy函數:  char *strcpy( char *dst, char const *src);

Note:

1.複製字串也會複製NUL位元組;

2.如果dst目標字元數組空間不足以容納需要複製的字串,strcpy將侵佔數組後面的部分記憶體空間(因為strcpy無法判斷目標字元數組的長度,這也是”不受限制“的含義吧)

——》連接字串 strcat函數: char *strcat( char *dst, char const *src );

Note:

1.這個函數找到dst的末尾(NUL位元組嗎),把src字串的一份拷貝添加到這個位置

2.這個函數也有strcpy的特點,如果dst空間不足以容納需要複製的字串了,則也將侵佔數組後面的部分空間

——》字串比較 strcmp: int strcmp(char const *s1, char const *s2);

Note:

1.這個函數的結果符合“字典比較”


****************************************************

9.4 長度指定了限制的字串函數

上面沒有受限的函數是以尋找字串結尾的NUL位元組來判斷長度;這裡的函數指定進行複製或比較的字元數

——》strncpy函數:char *strncpy( char *dst, char const *src, size_t len );

Note:

1.把源字串src的指定數目字元複製到目標數組dst;如果src沒有len個字元,則會用NUL位元組填充到dst

2.如果是strlen(src)大於len,那麼只有len個字元會進行複製。!但是,它的結果將不會以NUL位元組結尾。(也就是說,strncpy調用的結果可能不是一個字串哦)

——》strncat函數:char *strncat( char *dst, char const *src, size_t len);

Note:

1.strncat在串連完後,會自動在結果後加上一個NUL(因此這還是比較安全的,不會因為沒有NUL而在其他函數中出現問題),例如下程式

#include <string.h>#include <stdio.h>int main(){char *src = "world";char dst[7] = "hello";strncat(dst, src, 5);printf("%s", dst);return 0;}

因為dst容量(7)不夠裝下helloworld(11),因此strncat會侵佔幾個dst後面的位元組,但是在侵佔完後,strncat還是會加上一個NUL位元組。因此既有不安全的一面(侵佔後續位元組)也有安全的一面(自動加NUL位元組)

2.在src的長度不夠len時,它不會用NUL位元組繼續填充dst

*************************以下是一些相關的辨析

#include <string.h>#include <stdio.h>int main(){char *src = "world";printf("length of src is %d\n", sizeof(src));printf("length of src is %d\n", strlen(src));char dst[7] = "hello";int mat[100];strncat(dst, src, 9);printf("%s\n", dst);printf("length of dst is %d\n", sizeof(dst));printf("length of src is %d\n", sizeof(src));printf("length of src is %d\n", strlen(src));printf("length of mat is %d\n", sizeof(mat));return 0;}
運行結果為



這說明了幾點:

1.對於數組名來說,一般是作為指標,但是在sizeof(數組名)中,是求取了數組佔用的“位元組”數;

2.在strncat後,輸出helloworld後,對dst數組求位元組數卻還是7. 說明數組長度是被記錄下來的,不會變化了。但是往後只要用%s格式輸出dst,都會輸出helloworld。因為在後面都加入了‘\0‘;

3.完全不解!為什麼在開始strlen(src)還有5,但是在調用了strncat之後strlen(src)就只有1了?求解答~


再看以下的程式

#include <string.h>#include <stdio.h>int main(){//1        *src = "hello";printf("length of src is %d\n", sizeof(src));// 2printf("length of 'hello' is %d\n", sizeof("hello"));// 3char haha[] = "hello";printf("length of haha is %d\n", sizeof(haha));return 0;}


運行結果為


這說明了以下幾點:

1. 行1&2結合,我的分析是,在1中src在可重定位目標檔案中是一個存在於符號表中的標識符,是一個指標變數,以常量字串“hello”的起始地址初始化(運行時);而在2中“hello”是一個常量字串,在運行前已經存放好,放在可重定位目標檔案(編譯彙編之後,連結之前產生的檔案).rodata segment中(?不對耶,用objdump查看了,行1中的“hello”確實存放在rodata段中,但是sizeof(“hello”)中的“hello”沒有放在rodata中,因為若刪去第1行,則rodata中沒有hello了,如是刪去了第1行兩句話)


2.結合2&3分析,說明字元數組包含了‘\0‘


【C】字串,字元和位元組(C與指標第9章)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.