2014-11-23 72 views
2

所以我玩指針來理解不同的用例,我沒有如此經驗,無法繞過我的頭一些想法。我會標記出我有問題的地方。 請幫我理解指針。第6行玩指針,昏迷和char *字符串

爲什麼我不能指代一個字符串數組,因爲這是它是如何存儲在內存中,我認爲。 如何訪問字符串的單個字符?

上線7-8:

爲什麼會出現的8個字節&str&str + 1之間的差時int數據類型需要4個字節

上線9,10和12:

爲什麼是否使用*str來表示以int作爲輸入的字符串? 以及爲什麼它會將單個字節char轉換爲int而不是投射4個字節?

char *str = "Ninechars"; 
printf("Start\n"); 
printf("%s\n", str); 
printf("%p\n", str); // address of first char of str 
printf("%p\n", str+1); // address of second char of str 
// printf("%s\n", str[1]); // [segfault] warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [TODO] 
printf("%p\n", &str); // address to head of the string? NO, address of the pointer var str 
printf("%p\n", &str+1); // [TODO], difference of 8bytes b/w this and previous address value? [WHY]? 
printf("%d\n", *str); // what integer is this? -> whatever can be made from 'N'=78 
printf("%d\n", *(str+1)); // 'i'=105, but why is it taking single byte ints [TODO] 
printf("%ld\n", sizeof(1)); // 4 bytes, as expected 
// printf("%s\n", *str); // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO] 
printf("End\n"); 
 
Output: 
Start 
Ninechars 
0x40088f 
0x400890 
0x7fff95a594e8 
0x7fff95a594f0 
78 
105 
4 
End 

完整的代碼文件是在這裏:http://ideone.com/ryag80

+1

第6行需要一個'const char *',你給它一個'char'。同樣與第12行。 – WhozCraig 2014-11-23 07:03:20

+0

當您爲轉換說明符給出無效參數時,它是未定義的行爲。雖然這可能不是你想聽到的。 – 2014-11-23 07:04:46

+0

[WhozCraig](http://stackoverflow.com/users/1322972/whozcraig)謝謝!清除了一些東西,但它爲什麼會恢復爲'int'?這是默認的機制嗎? – abhik 2014-11-23 07:14:20

回答

3

讓我們來看看它逐行:


char *str = "Ninechars"; 
printf("Start\n"); 
printf("%s\n", str); 
printf("%p\n", str); // address of first char of str 
printf("%p\n", str+1); // address of second char of str 

上述地址是進程的數據段的一部分' 虛擬內存。


printf("%s\n", str[1]); 

其實,str[1] == *(str + 1)%s期望的是char *,因此(str + 1)&str[1]


printf("%p\n", &str); 
printf("%p\n", &str+1); 

&strstr地址,指針char。它在堆棧上。

8字節的差異意味着,在您的系統上的,指向char的指針的大小是8個字節。嘗試printf("\nsizeof(char*) == %zd\n", sizeof(char*))來驗證它。


printf("%d\n", *str); 

ASCII codeN


printf("%d\n", *(str+1)); 

事實上'i' == 105ASCII code再次),你指示printf()int使用%d打印。


printf("%ld\n", sizeof(1)); // 4 bytes, as expected 
printf("%s\n", *str); // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO] 

同樣,使用%sprintf()需要字符串(char *在C),但*str實際上是一個char(8字節int)。

+0

[chrk](http://stackoverflow.com/users/2304215/chrk)非常感謝!只是多一個查詢,我怎麼知道哪些地址屬於堆棧,哪些屬於堆棧? – abhik 2014-11-23 09:19:58

+0

@abhik:局部變量存儲在堆棧中,'malloc'變量存儲在堆中。如果您注意到打印地址的值,則可以驗證堆棧是否在進程的虛擬內存的開始位置,而堆棧是否在最後。我相信[這個問題](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap)是有趣和有教育意義的,可以更多地瞭解堆棧和堆。 – chrk 2014-11-23 14:37:21