C 中char 和char 的區別

2021-10-14 19:27:29 字數 3246 閱讀 7735

例如如下**:

#includeusing namespace std;

int main()

這二者的區別還在於:

p1是乙個指標變數,有一塊記憶體儲存它,它的內容是字串的位址,那麼我們要訪問字串就先要取出p1中儲存的位址,然後計算偏移量,進行訪問

不同於p1,p2直接是字串的位址,直接訪問就行了

「abcd」是文字常量區分配了記憶體儲存的,棧上分配一位址給p1並指向「abcd」,那麼如果在後面的**中改變了「abcd」,自然崩潰。所以,需要加上const限定

但是說到底,為什麼改變p1就是危險的,字元陣列的內容就能隨意改變呢?這是因為「abcd」是在編譯時刻就確定的,而「1234」是在執行時刻賦值的。所以,編譯器在編譯時就已經知道p1指向的是常量,他並不希望你改變,但是陣列不同,可以說他只是個儲存的工具,編譯器編譯時並不知道它裡面是什麼。

但在往後的訪問中,在棧上的陣列比指標所指向的字串是要快的。

還網上找到如下**,很詳細

int a=0;    //全域性初始化區

char *p1; //全域性未初始化區

main()

#includeusing namespace std;

int main()

c++記憶體被分為5個區,分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。現在來分析一下所以資料的記憶體分布:

char str1 = "abc";

char str2 = "abc";

這裡的"abc"是乙個常量,首先會在常量儲存區里儲存"abc"這個常量,然後會因為"abc"被賦值給str1,所以在棧中開闢一段記憶體,記憶體大小為4個節點(char陣列後會自動加乙個』\0』),然後又有乙個"abc"被儲存在棧中。

同理,str2中的"abc"也是儲存在棧中,位址不同。

到此,有三個"abc"被儲存起來,乙個在常量儲存區,另外兩個在棧中。

str1:0x0x7ffea5a7c543

str2:0x0x7ffea5a7c547

const char str3 = "abc";

const char str4 = "abc";

str3:0x0x7ffea5a7c54b

str4:0x0x7ffea5a7c54f

對於這種被const修飾起來的變數,一般也是被儲存在常量儲存區,但是,但是對於const陣列來講,系統不確定符號表是否有足夠的空間來存放const陣列,所以還是為const陣列分配記憶體的。所以str3指向的是棧上的"abc"。

同理,str4也是儲存在棧中,位址不同。

const char *str5 = "abc";

const char *str6 = "abc";

char *str7 = "abc";

char *str8 = "abc";

str5:0x0x7fc215ec100a

str6:0x0x7fc215ec100a

str7:0x0x7fc215ec100a

str8:0x0x7fc215ec100a

因為"abc"在常量儲存區中儲存有乙份(即使沒儲存,這樣的操作也會新建乙份),這裡str5定義的時候,str5就直接指向"abc"所在的常量區的位址。同理str6,str7,str8。與const沒有半毛錢關係,const只是使得str5和str6無法指向新的字串常量(也就是新的位址)。

__attribute ((packed)) 是為了強制不進行4位元組對齊,這樣比較容易說明問題。

struct tag __attribute ((packed));

struct tag1 __attribute ((packed));

printf("int-sltren:%d\n", sizeof(int));

printf("tag-sltren:%d\n", sizeof(tag));

printf("tag1-sltren:%d\n", sizeof(tag1));

char *-sltren:8

int-sltren:4

tag-sltren:12

tag1-sltren:4

#includeusing namespace std;

struct tag ;

struct tag1 ;

int main()

char *-sltren:8

int-sltren:4

tag-sltren:16

tag1-sltren:4

#include #include #include struct tag1

__attribute ((packed));

struct tag2

__attribute ((packed));

struct tag3

__attribute ((packed));

struct tag4

__attribute ((packed));

int main()

size of tag1 = 8

size of tag2 = 16

size of tag3 = 8

size of tag4 = 9

l_tag2 = 0x7ffdd3e11450,&l_tag2.c = 0x7ffdd3e11458,l_tag2.c = (nil)vivi

l_tag3 = 0x7ffdd3e11467,l_tag3.c = 0x7ffdd3e1146f

l_tag4 = 0x7ffdd3e1146f,l_tag4.c = 0x7ffdd3e11477

說明在結構體裡面, char* buf 和char buf[1]的效果差不多(這個是在對齊的情況下,不對齊的話也是不一樣的),佔4個位元組;char buf[0] 和char buf是一樣的,不佔記憶體。

從上面程式和執行結果可以看出:tag1本身包括兩個32位整數,所以佔了8個位元組的空間。tag2包括了兩個32位的整數,外加乙個char *的指標,所以佔了12個位元組。tag3才是真正看出char c[0]和char *c的區別,char c[0]中的c並不是指標,是乙個偏移量,這個偏移量指向的是a、b後面緊接著的空間,所以它其實並不占用任何空間。tag4更加補充說明了這一點。

c 中char 和 char 的區別

問題引入 在實習過程中發現了乙個以前一直預設的錯誤,同樣char c abc 和char c abc 前者改變其內 容程式是會崩潰的,而後者完全正確。程式演示 測試環境devc include using namespace std main 執行結果 2293628 4199056 abc 229...

c 中char 和 char 的區別

問題引入 在實習過程中發現了乙個以前一直預設的錯誤,同樣char c abc 和char c abc 前者改變其內 容程式是會崩潰的,而後者完全正確。程式演示 測試環境devc include using namespace std main 執行結果 2293628 4199056 abc 229...

c 中char 和 char 的區別

問題引入 在實習過程中發現了乙個以前一直預設的錯誤,同樣char c abc 和char c abc 前者改變其內 容程式是會崩潰的,而後者完全正確。程式演示 測試環境devc include using namespace std main 執行結果 2293628 4199056 abc 229...