国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

scanf函數(shù)調(diào)用過(guò)程的實(shí)現(xiàn)機(jī)制分析

2014-06-20 01:46:56張春玲
無(wú)線互聯(lián)科技 2014年2期
關(guān)鍵詞:函數(shù)調(diào)用字符串緩沖區(qū)

張春玲

摘 要:scanf函數(shù)是C語(yǔ)言中最基本的輸入函數(shù),本文通過(guò)分析scanf函數(shù)調(diào)用過(guò)程中的實(shí)現(xiàn)機(jī)制,以幫助正確使用scanf函數(shù)。

關(guān)鍵詞:C;scanf函數(shù)調(diào)用;實(shí)現(xiàn)機(jī)制

1 scanf函數(shù)

scanf的功能是從標(biāo)準(zhǔn)輸入設(shè)備讀取輸入的任何固有類型的數(shù)據(jù)自動(dòng)轉(zhuǎn)換成機(jī)內(nèi)格式并把數(shù)據(jù)輸入到指定的變量之中,返回正確讀入數(shù)值的個(gè)數(shù)。函數(shù)原型主要代碼如下:

int_cdecl scanf(const char *format,...)

{va_list arg;

va_start(arg,format);

return vscanf(_input_l,format,NULL,arg);}

2 scanf函數(shù)調(diào)用

2.1 調(diào)用格式

scanf(格式控制,地址表列);“格式控制”為格式字符串,將用戶輸入的數(shù)據(jù)轉(zhuǎn)換為指定格式;“地址表列”由若干個(gè)地址組成的參數(shù)表列,可以是變量的地址或字符串首地址。原型中_cdecl是c中的默認(rèn)函數(shù)調(diào)用方式,調(diào)用函數(shù)參數(shù)自右向左入棧,因此scanf函數(shù)左邊的第一個(gè)參數(shù)format被放于棧頂。

2.2 參數(shù)入棧

C調(diào)用協(xié)議下,為遵循對(duì)齊原則,要求每個(gè)變量地址都是sizeof(int)的倍數(shù),因此參數(shù)入棧都是整數(shù)字節(jié)。同時(shí)調(diào)用不帶原型聲明的函數(shù)時(shí),調(diào)用者會(huì)對(duì)每個(gè)參數(shù)執(zhí)行“默認(rèn)實(shí)際參數(shù)提升”。從scanf函數(shù)調(diào)用格式中,可變參數(shù)是若干個(gè)地址列表(指針),C中為每個(gè)指針變量統(tǒng)一分配4個(gè)字節(jié),即可變參數(shù)入棧時(shí)都占用4個(gè)字節(jié),滿足了對(duì)齊原則,與指針指向的變量類型沒(méi)有關(guān)系。這與printf函數(shù)調(diào)用時(shí)參數(shù)入棧不一樣。

2.3 格式字符串與標(biāo)準(zhǔn)輸入流的匹配

參數(shù)入棧后,編譯器先獲取格式字符串,對(duì)照字符串中的各項(xiàng),從內(nèi)存緩沖區(qū)中取數(shù)據(jù),若沒(méi)有數(shù)據(jù),則等待用戶輸入。用戶通過(guò)鍵盤(pán)輸入數(shù)據(jù),數(shù)據(jù)回顯于顯示器上,同時(shí)數(shù)據(jù)被存入內(nèi)存緩沖區(qū)(不是鍵盤(pán)緩沖區(qū))中。為什么?scanf源碼中,函數(shù)功能的實(shí)現(xiàn)依靠vscanf函數(shù)調(diào)用_input_l,而_input_l的函數(shù)功能是把鍵盤(pán)輸入數(shù)據(jù)寫(xiě)入stdin(標(biāo)準(zhǔn)輸入流)來(lái)創(chuàng)建一個(gè)臨時(shí)交換文件的緩沖區(qū),只有當(dāng)用戶輸入回車后,scanf函數(shù)開(kāi)始從內(nèi)存緩沖區(qū)取數(shù)據(jù)。在接收數(shù)據(jù)時(shí),對(duì)照字符串的各項(xiàng),并按匹配規(guī)則,逐一取數(shù):內(nèi)存緩沖區(qū)中,讀取時(shí)順序讀取寫(xiě)入的數(shù)據(jù),即先讀先寫(xiě)入的數(shù)據(jù)再讀后寫(xiě)入的數(shù)據(jù),這與對(duì)字符串中從左到右匹配順序一致,匹配規(guī)則如下:C99中,格式字符串有如下三種類型字符:

⑴格式說(shuō)明符:遇到格式說(shuō)明符去讀取緩沖區(qū)時(shí),匹配分兩步,首先是格式字符與緩沖區(qū)數(shù)據(jù)類型匹配,然后格式字符與對(duì)應(yīng)參數(shù)指向的變量類型匹配。匹配時(shí)先將緩沖區(qū)中一個(gè)或多個(gè)連續(xù)的空白字符(格式字符為字符型除外)移出并去掉,再將格式符與緩沖數(shù)據(jù)進(jìn)行匹配(見(jiàn)(四)),若類型匹配,則讀取緩沖區(qū)中直到遇到非法字符(與指定類型不匹配的字符)或者達(dá)到輸出寬度要求前的數(shù)據(jù),再將數(shù)據(jù)送到與格式字符類型匹配的變量中去(借助三個(gè)宏va_start;va_arg;va_end訪問(wèn)后面每個(gè)參數(shù))。若格式字符類型與緩沖區(qū)數(shù)據(jù)不匹配,stdin流被阻塞,scanf函數(shù)不在讀取后面的部分。若格式字符與后面的參數(shù)類型不一致,則丟棄數(shù)據(jù)。

因此匹配格式字符時(shí),輸入流中開(kāi)始讀取到的空白字符(尤其對(duì)字符串中多個(gè)數(shù)值型格式字符緊挨著時(shí),需要輸入的一個(gè)或多個(gè)空白字符)對(duì)匹配沒(méi)有任何影響,自動(dòng)略去。也就是匹配格式字符時(shí),輸入流中可以輸入任意多個(gè)空白字符。如scanf(“%d”,&a);輸入時(shí)可以直接輸入整數(shù),也可以輸入一個(gè)或者多個(gè)空白字符再輸入整數(shù),結(jié)果一樣。

⑵空白符:可以是空格、制表符和新行符。字符串中的空白字符的作用是使scanf函數(shù)在讀操作中略去輸入流中的一個(gè)或多個(gè)空白字符。因此,空白符是使scanf在輸入流中讀,但不保存結(jié)果,直到發(fā)現(xiàn)非空白字符為止,同時(shí)將棧中字符串位置指向下一個(gè)非空白字符。

因此匹配空白字符時(shí),入棧的空白字符與輸入流中不一定匹配,因?yàn)檫@時(shí)候字符串中的空白字符對(duì)字符串來(lái)說(shuō)就是一個(gè)分隔符,輸入數(shù)據(jù)時(shí)用戶即可以輸入相同個(gè)或更多個(gè)空白字符也可以不輸入(當(dāng)多個(gè)數(shù)值型格式字符由空白字符隔開(kāi)時(shí),在輸入時(shí)必須輸入空白字符),對(duì)讀取數(shù)據(jù)沒(méi)有任何影響,因?yàn)樽址锌瞻鬃址梢月匀ポ斎肓髦械亩鄠€(gè)連續(xù)空白字符。

⑶非空白符:使scanf()根據(jù)棧中字符在流中讀匹配的字符并放棄。如“a=%d”,使scanf讀取流中a=并放棄,如未發(fā)現(xiàn)匹配,scanf()返回。若字符串中非空白字符前面沒(méi)有空白字符,在輸入數(shù)據(jù)時(shí),一定不要輸入空白字符。例:scanf(“a=%d”,&a);輸入時(shí)第一字符只能是a,若是空格則結(jié)果不對(duì)。棧中的a與輸入流中的空格不匹配,因?yàn)榭瞻鬃址粫?huì)自動(dòng)略去。

2.4 格式字符匹配輸入流中的數(shù)據(jù)

如f,則告訴scanf接收數(shù)據(jù)的變量是float類型,需從輸入流中讀取一個(gè)單精度數(shù),再放入float類型變量中;如果將 L/l放在前面,則告訴scanf接收數(shù)據(jù)的變量為double??梢钥闯鲚斎霑r(shí)區(qū)別%f,%lf的,這與printf函數(shù)不同。使用printf時(shí),f遵循提升規(guī)則表示double類型。而scanf匹配時(shí)首先是根據(jù)格式字符類型讀取數(shù)據(jù),再將數(shù)據(jù)輸入對(duì)應(yīng)變量。假如scanf中f代表double,表示從輸入流讀取雙精度數(shù),若%f對(duì)應(yīng)的變量是單精度,那不能保證將一個(gè)double型的數(shù)放到一個(gè)float類型中,原因是定義變量時(shí)float,double分別分配4個(gè)字節(jié),8個(gè)字節(jié),向變量輸入數(shù)據(jù)時(shí)是受字節(jié)限制的。因此輸入數(shù)據(jù)時(shí)要區(qū)分float,double,%f代表兩種類型不行。

3 總結(jié)

scanf函數(shù)在C中應(yīng)用比較頻繁,本文詳細(xì)分析了scanf函數(shù)調(diào)用過(guò)程,重點(diǎn)分析了格式字符串中三種類型的字符與內(nèi)存緩沖區(qū)匹配的過(guò)程,希望對(duì)使用scanf函數(shù)有正確指導(dǎo)意義。

[參考文獻(xiàn)]

[1]譚浩強(qiáng).C語(yǔ)言程序設(shè)計(jì)[M].北京.清華大學(xué)出版社.2011.

[2]徐娟.可變參函數(shù)scanf的執(zhí)行過(guò)程分析[J].信息與電腦.2013.5.

猜你喜歡
函數(shù)調(diào)用字符串緩沖區(qū)
嵌入式系統(tǒng)環(huán)形緩沖區(qū)快速讀寫(xiě)方法的設(shè)計(jì)與實(shí)現(xiàn)
基于C語(yǔ)言的數(shù)學(xué)菜單的設(shè)計(jì)與實(shí)現(xiàn)
基于函數(shù)調(diào)用序列模式和函數(shù)調(diào)用圖的程序缺陷檢測(cè)方法*
探討C++編程中避免代碼冗余的技巧
Unity3D項(xiàng)目腳本優(yōu)化分析與研究
關(guān)鍵鏈技術(shù)緩沖區(qū)的確定方法研究
一種新的基于對(duì)稱性的字符串相似性處理算法
依據(jù)字符串匹配的中文分詞模型研究
地理信息系統(tǒng)繪圖緩沖區(qū)技術(shù)設(shè)計(jì)與實(shí)現(xiàn)
電視技術(shù)(2012年1期)2012-06-06 08:13:58
承德县| 遂溪县| 延庆县| 天门市| 建平县| 屏东县| 怀集县| 海盐县| 云林县| 合肥市| 类乌齐县| 崇仁县| 湘潭县| 拉萨市| 澎湖县| 成安县| 曲周县| 旬阳县| 鄂托克旗| 福鼎市| 西华县| 抚松县| 万荣县| 阳城县| 麻阳| 福海县| 佛坪县| 海宁市| 广西| 方城县| 磐石市| 大足县| 潜山县| 伊宁市| 钦州市| 芮城县| 东阳市| 镶黄旗| 五寨县| 建德市| 榆树市|