消失的字符串——c语言函数中的数据存储方式以及字符串实现
2019獨角獸企業重金招聘Python工程師標準>>>
????????事情是這樣的,最近在學習翁老師的Mooc之C語言程序設計,插一句,真的是好老師,講的真的太好了,在c里的字符串這里,翁老師演示了一個小程序,大概代碼如下,無非就是想給我們說明c語言的scanf讀入字符串是遇到空格、Tab和回車為止,并且會在結尾自動加上表示字符串結束的‘\0’,然后想給我們演示如果出現字符數組越界會怎樣?!就出現了如下的示例:
#include?<stdio.h>int?main() {char?word[8];char?word2[8];scanf("%s",word);scanf("%s",word2);printf("%s##%s\n",word,word2);return?0; }????????????????????????????
????????如上就是程序運行結果,有沒有覺得很神奇,反正當時我是震驚了,WoW,太不可思議了,這究竟發生了什么,老師也留下了這個疑問給我們,留下我們苦苦思索,但是百思不得其解,天哪,還好老師給了一個小提示,這和c語言中的數據在計算機中的存放方式有關。
????????于是我開始思考,我仿照翁老師的做法,反正c語言提供了這樣的工具——指針,我們就輸出地址來看看,我也是知道的,函數在計算機中是通過堆棧的方式來實現的,數據就是通過堆棧來保存,堆棧是很重要的數據結構,其有一個很重要的特性,FILO,后進先出。我增加了輸出字符數組每個元素的地址的代碼,如下:
#include?<stdio.h> int?main() {char?word[8];char?word2[8];scanf("%s",word);scanf("%s",word2);printf("%s##%s\n",word,word2);printf("%p\n",word);printf("%p\n",word2);printf("\n");int?i;for(i=0;i<8;i++){printf("%p\n",&word[i]);}printf("\n");for(i=0;i<8;i++){printf("%p\n",&word2[i]);}return?0; }????????????????????????????????????
????????看到了輸出地地址后,加上草圖,一切都簡單明了了,總結如下:
????????在32位的架構下(我是在32位下編譯的,其實在64位下沒有出現這個情況,那是因為64位下存儲字大小又不同了,其實我還不太解釋的明白,留一個問號???但是通過相同程序的運行,我們能夠發現不同,word和word2之間的地址差為16個字節,當我將字符數組大小擴大為20時,地址差是按一個存儲字增加的,那64位的存儲字就應該為16字節,這也確實符合計算機組成里講的對齊的方式存儲),因為函數是通過堆棧來存儲變量的,是高地址向低地址存儲,我們可以把一個字符數組想成一個存儲字,在字內是順序存儲的,就是從低地址向高地址,而存儲字間是則是堆棧的順序,是一種小端存放的方式,這里,word和word2看成指針是const的,是不變的,當scanf讀入第一個12345678‘\0’字符串的時候是從word所指的位置向高地址依次寫入,雖然越界到了規定的位置以外,但是c語言并沒有提供有效的機制,即使這是不安全的,但是我們依然可以做,可以順利的寫入,然后讀入第二個12345678‘\0’字符串的時候,同樣的方式,從word2所指向的位置向高地址寫入,很不幸的是,在定義字符數組的時候大小就決定了,并且是連續的分配的內存空間,所以寫入到8的時候,其實就用完了定義的word2的數組大小,但是字符串末尾還有結束字符'\0',雖然是不安全的,但是c語言的編譯器不會發現,因此'\0'被繼續寫到了接下來連續的地址中,就是word所指向的位置,寫入就將原來的1所覆蓋,讀入就ok了,接下來是打印,首先先打印word所指向的字符串,第一個已經重新寫入了,剛好是字符串結束字符,因此什么也不輸出,然后是打印word2所指向的字符串,打印1.。。。一直要到'\0'才會認為是字符串的結束,所以就打印出了12345678‘\0',說到這里,我也就基本明白了字符串消失之謎的真相,用柯南的話,真相永遠只有一個!
????????哦,原來是這樣,果然不是我不明白,而是我并不知道,計算機的世界真的很精彩,而且很有意思,等著我,我一定要好好看看。
????????
轉載于:https://my.oschina.net/fchen24/blog/664079
總結
以上是生活随笔為你收集整理的消失的字符串——c语言函数中的数据存储方式以及字符串实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一剪梅
- 下一篇: 【男人必看十大经典】[经典合集][DVD