char*s = 「hello world」 是否是字符串?

  用C/C++的老鐵們可能對這個都比較熟悉。char* s = "Hello World";這樣定義字符串很簡單呀,很方便。不用去考慮大小呀什麼的,簡單快捷。是,這樣子是挺方便,並且編譯也不會報錯會經過,程序也能跑,可是實際上,這樣子作是很差的,嚴格意義上來說,這樣實際上是定義了一個野指針。下面咱們就用一段代碼來闡述這件事情。數組

  

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()  5 {  6 
 7     char* s = "hello world";  8     char* s1 = "hello world";  9     printf("s = %s\n", s); 10     printf("s1 = %s\n", s1); 11     printf("addr_s = %p\n", s); 12     printf("addr_s1 = %p\n", s1); 13 }

  咱們按照這種方式定義了兩個「字符串」,咱們經過printf函數看一下這個字符串可否正常的輸出,而且咱們也看一下s和s1在內存中的地址。安全

  

  最終咱們看到雖然程序報了兩個warning,可是程序依然能夠繼續運行。經過程序的輸出咱們能夠看到,s和s1都可以正常的輸出咱們想要的hello world字符串。可是有一個地方值得注意,s和s1擁有着相同的地址。那麼是否是全部的字符串都是這樣的呢,咱們換一種方式去定義。函數

  

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()  5 {  6 
 7     char* s = "hello world";  8     char* s1 = "hello world";  9     printf("s = %s\n", s); 10     printf("s1 = %s\n", s1); 11     printf("addr_s = %p\n", s); 12     printf("addr_s1 = %p\n", s1); 13     char s2[12] = "hello world"; 14     char s3[12] = "hello world"; 15     printf("s2 = %s\n", s2); 16     printf("s3 = %s\n", s3); 17     printf("addr_s2 = %p\n", s2); 18     printf("addr_s3 = %p\n", s3); 19     
20 }

  咱們經過數組的形式又去定義了兩個字符串,這下咱們再去看一下程序的輸出。spa

  

  咱們看到,此次s2和s3並沒具備相同的地址,並且值得注意的是,s、s1和s二、s3的內存地址相差較大。這是爲何呢?其實這是由於char* s = "hello world",這個操做是操做系統幫你完成的。本事char*s是一個野指針,咱們並不知到「hello world」這個內容在哪,可是卻讓一個指針去指向它。那麼不知道該指向誰的指針要怎麼作呢?操做系統就會在特定的一個區域去幫它建立出這樣的一塊內存去存放「hello world」而後讓這個指針去指向它。並且這塊特殊的內存並非屬於程序自己的,而是屬於操做系統的,那麼這樣就會形成你只能夠去讀這塊區域,他不會容許你去修改這一塊區域。這就是操做系統的保護機制,任何操做系統都是這樣。操作系統

  因此咱們在定義字符串的時候就要有所考慮,何時用char* s 這樣的字符串,何時用char s[12]這樣的字符串。簡單的說,若是你只是定義了一個字符串,後來並不會對他進行一些操做,那麼你能夠用這種char* s形式字符串,或者你想定義一個函數去接收一個字符串類型的參數也能夠用這種字符串。若是想要後續的對字符串進行大量的操做,最好用數組類型的字符串,由於它不會去佔用系統的內存,這樣你就對這個字符串擁有了相對較高的權限。指針

  因此char* s是一個字符串,只不過是一種權限比較低的字符串,它的使用並不安全,也並不完美——由於相同的字符串會佔用同一個內存地址,因此在使用的過程當中要多加考慮。code

相關文章
相關標籤/搜索