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

?

C語(yǔ)言學(xué)習(xí)常見(jiàn)誤區(qū)探析

2020-07-07 07:48:10楊存?zhèn)?/span>汪維清
鄂州大學(xué)學(xué)報(bào) 2020年2期
關(guān)鍵詞:編譯器初學(xué)者指針

楊存?zhèn)?,汪維清

(西南大學(xué) 信息管理系,重慶 402460)

計(jì)算機(jī)相關(guān)專(zhuān)業(yè)學(xué)生的第一門(mén)編程語(yǔ)言往往是C語(yǔ)言,作為一門(mén)高級(jí)語(yǔ)言,有一定的抽象性。未接觸過(guò)計(jì)算機(jī)科學(xué)的初學(xué)者,往往會(huì)因?yàn)楦鞣N原因形成一些理念誤區(qū),學(xué)習(xí)理念出錯(cuò)會(huì)導(dǎo)致事倍功半,使初學(xué)者喪失學(xué)習(xí)興趣。

1 認(rèn)為僅學(xué)習(xí)C語(yǔ)言可以理解計(jì)算機(jī)底層原理

C語(yǔ)言具有一定的抽象性,初學(xué)者在學(xué)習(xí)C語(yǔ)言大多無(wú)編程經(jīng)驗(yàn),C語(yǔ)言教材往往會(huì)較為抽象地介紹C語(yǔ)言,而不具體講解涉及的底層原理,因?yàn)檫@更有助于初學(xué)者編程入門(mén)。

例一:以一個(gè)C語(yǔ)言版本的以遞歸方法尋找兩個(gè)正整數(shù)最大公約數(shù)的程序?yàn)槔齕1]:

數(shù)組,函數(shù),判斷語(yǔ)句等基本語(yǔ)法在常見(jiàn)的編程語(yǔ)言中都有,相對(duì)不那么“底層”的Python,C#,Java等都可實(shí)現(xiàn)這個(gè)算法,與編程語(yǔ)言的種類(lèi)關(guān)系較小。

很多C語(yǔ)言的資料講到,arr是一個(gè)指針,它保存內(nèi)存的一個(gè)地址,通過(guò)此地址可訪(fǎng)問(wèn)內(nèi)存中一個(gè)int型數(shù)據(jù),誤操作指針會(huì)導(dǎo)致程序錯(cuò)誤甚至系統(tǒng)崩潰[2]。初學(xué)者往往理解為arr保存的是物理地址,雖不影響程序?qū)崿F(xiàn),但并不準(zhǔn)確。

以32位的使用NT內(nèi)核的Windows為例,在Windows中,每個(gè)進(jìn)程都有自己的虛擬地址空間(0x00000000~0xFFFFFFFF),指針arr保存了虛擬地址空間的地址,而非物理內(nèi)存地址。指針arr所指向的數(shù)據(jù)可能存儲(chǔ)在物理內(nèi)存中,可能在硬盤(pán)上(由于Windows虛擬內(nèi)存技術(shù)),也可能在其他地方[3]。

誤操作指針可以導(dǎo)致系統(tǒng)崩潰或硬件損壞,但是初學(xué)者編寫(xiě)的此類(lèi)簡(jiǎn)單控制臺(tái)程序很難導(dǎo)致系統(tǒng)崩潰或硬件損壞,相對(duì)來(lái)說(shuō),編寫(xiě)Windows內(nèi)核模式驅(qū)動(dòng)程序,單片機(jī)控制程序這樣的偏底層的程序才易因指針問(wèn)題出現(xiàn)嚴(yán)重錯(cuò)誤。操作系統(tǒng)中進(jìn)程之間相對(duì)獨(dú)立,在Windows操作系統(tǒng)中,一個(gè)進(jìn)程若需要訪(fǎng)問(wèn)另一個(gè)進(jìn)程的數(shù)據(jù),可以調(diào)用Write Process Memory函數(shù)、使用DLL注入技術(shù)、創(chuàng)建內(nèi)存文件映射對(duì)象共享數(shù)據(jù)等,而一個(gè)簡(jiǎn)單的指針問(wèn)題很難辦到。

以上涉及到計(jì)算機(jī)組成原理,操作系統(tǒng)原理中的知識(shí),只學(xué)習(xí)C語(yǔ)言本身,即使屏蔽掉這些知識(shí),也可以做到寫(xiě)出有一定復(fù)雜度的程序。初學(xué)者較難理解的概念,如函數(shù)指針,共用體,可以用抽象的方式理解,學(xué)習(xí)計(jì)算機(jī)科學(xué)可以是從頂層向底層和從底層向頂層相結(jié)合的。

例二:直接調(diào)用Windows API編寫(xiě)窗體程序的代碼片段

對(duì)于初學(xué)者來(lái)說(shuō),宏定義的用法,函數(shù)的編寫(xiě)方法,switch語(yǔ)句的使用等并不困難,上述代碼沒(méi)有涉及不常見(jiàn)的語(yǔ)法,但初學(xué)者并不容易理解,Windows API編寫(xiě)窗體程序涉及到很多Windows操作系統(tǒng)的知識(shí)。

由以上兩例可以看出,僅憑C語(yǔ)言的學(xué)習(xí),不能理解計(jì)算機(jī)的底層原理。作為一種高級(jí)語(yǔ)言,能夠提供的抽象程度可以允許一定范圍內(nèi)忽略硬件及操作系統(tǒng)之類(lèi)的細(xì)節(jié)而編寫(xiě)程序,所以對(duì)于初學(xué)者來(lái)說(shuō)不管學(xué)習(xí)Python,Java,C#還是C語(yǔ)言,都不會(huì)直接了解底層的原理,C語(yǔ)言只是相對(duì)來(lái)說(shuō)能更好的引申出這些知識(shí)而已。

2 編寫(xiě)代碼過(guò)于復(fù)雜

源代碼應(yīng)是方便程序員閱讀和修改的,越復(fù)雜,通常越難以維護(hù),更容易出錯(cuò)。在不影響程序的最終實(shí)現(xiàn)效果(比如不用位運(yùn)算就會(huì)嚴(yán)重拖慢運(yùn)行速度)的前提下,應(yīng)該使代碼更通俗易懂。但是,初學(xué)者往往會(huì)“炫耀”技巧,使得代碼過(guò)于復(fù)雜、艱澀。

2.1 濫用技巧

例三:交換兩個(gè)變量的值

不考慮int的表示范圍以上代碼是沒(méi)有問(wèn)題的,但若*x+*y?[INT_MIN,INT_MAX]會(huì)溢出,這個(gè)函數(shù)便不能交換兩變量的值。而更易懂的寫(xiě)法應(yīng)該引入第三個(gè)變量進(jìn)行交換。

2.2 表達(dá)思路不清晰

例四:“HelloWorld!”轉(zhuǎn)化成大寫(xiě)輸出

這個(gè)程序的目的是將一串字符轉(zhuǎn)化成大寫(xiě)輸出,在禁用編譯器優(yōu)化的情況下,可能會(huì)調(diào)用很多次strlen函數(shù)。而且并非需要每次都調(diào)用printf函數(shù),可將其存入一個(gè)字符數(shù)組后一次性輸出。較合理的寫(xiě)法如下:

2.3 濫用不常用的特性

以下將C語(yǔ)言的庫(kù)函數(shù),語(yǔ)法等,統(tǒng)一稱(chēng)作C語(yǔ)言的特性。C語(yǔ)言教材的第一示例程序通常都是一個(gè)簡(jiǎn)單的”Hello World”,然后逐漸介紹新的特性,并要求讀者在程序中使用,會(huì)讓部分讀者有“學(xué)到新特性就要盡可能在程序中使用”的習(xí)慣,使用常用的,被大多數(shù)編譯器支持的特性是正常的,而不常用的,只被很少編譯器支持的特性,如_Generic關(guān)鍵字,_Noreturn函數(shù)標(biāo)記,_Atomic類(lèi)型修飾符和頭文件等,只有在需要使用并了解風(fēng)險(xiǎn)(可移植性,易讀性,編譯器是否完整支持)時(shí)才應(yīng)使用[4]。

如在判斷正整數(shù)的奇偶性,判斷整數(shù)的符號(hào)是否相同時(shí),不應(yīng)總是使用位運(yùn)算[5];有兩個(gè)有關(guān)聯(lián)的數(shù)據(jù)應(yīng)該使用結(jié)構(gòu)體而不是利用C99標(biāo)準(zhǔn)中定義的復(fù)數(shù)的實(shí)部和虛部進(jìn)行表示;在不需要特別注意內(nèi)存占用或沒(méi)有其他特殊需求時(shí)不使用“位域”等。

3 不注意undefined behavior(未定義行為)

例五:C語(yǔ)言源代碼

頭文件限定了特定平臺(tái)上int的表示范圍,而顯然INT_MAX+1超出了這一范圍。C語(yǔ)言標(biāo)準(zhǔn)沒(méi)有規(guī)定應(yīng)該接下來(lái)會(huì)發(fā)生什么,調(diào)用函數(shù)可能返回一個(gè)不可預(yù)見(jiàn)的值、程序崩潰、刪除磁盤(pán)上的某些文件等,出現(xiàn)任何結(jié)果編譯器都未違反C語(yǔ)言標(biāo)準(zhǔn)。在DOS上,在Windows 10上,在FreeBSD上,由于運(yùn)行環(huán)境和編譯器的實(shí)現(xiàn)方式不同,結(jié)果難以預(yù)測(cè),故即使在某一個(gè)平臺(tái)上利用反匯編的手段,也不能判定其他環(huán)境的結(jié)果。任何試題和教材都不應(yīng)該嘗試去判定這種語(yǔ)法現(xiàn)象一定會(huì)出現(xiàn)什么情況。未定義行為沒(méi)有明確的含義,因此也是錯(cuò)誤的代碼,但是C語(yǔ)言標(biāo)準(zhǔn)不要求編譯器報(bào)錯(cuò)或者給出警告[6]。

例六:求出a,b的值:

使用Visual C++6.0編譯,a,b分別為30和37,在更老的Turbo C 3.0中,a,b分別為30和39。這一歧義與序列點(diǎn)(sequence point)有關(guān)?!盿=(i++)+(i++)+(i++);”這樣的表達(dá)式?jīng)]有任何實(shí)際意義,是錯(cuò)誤的[7]。

除此之外,不確定行為(unspecified behavior),實(shí)現(xiàn)定義行為 (implementation-defined behavior)等也可能給程序造成意外的結(jié)果。

4 過(guò)于急切學(xué)習(xí)編寫(xiě)GUI程序

在PC、智能手機(jī)等設(shè)備上,接觸最多的是圖形化的界面,普通用戶(hù)很少使用命令行界面,初學(xué)者總想早一些能編寫(xiě)出來(lái)他們所熟悉的GUI程序,但編寫(xiě)程序,學(xué)習(xí)計(jì)算機(jī)科學(xué),不等于編寫(xiě)GUI程序。一些初學(xué)者學(xué)習(xí)了C語(yǔ)言以及計(jì)算機(jī)其他課程之后依然只能寫(xiě)出“黑框框”程序,十分焦躁。并非編寫(xiě)GUI程序就一定有技術(shù)含量,而編寫(xiě)算法程序,學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)原理,理解操作系統(tǒng)原理這些與GUI關(guān)系不大的就沒(méi)有技術(shù)含量。編寫(xiě)GUI程序有各種成熟的解決方案,如Windows平臺(tái)上的WPF技術(shù)、Java的JavaFX技術(shù)、Python的Tkinter模塊等,使用這些技術(shù)編寫(xiě)簡(jiǎn)單的GUI程序是十分容易的,而計(jì)算機(jī)相關(guān)專(zhuān)業(yè)的學(xué)生應(yīng)該將精力放在計(jì)算機(jī)組成原理、計(jì)算機(jī)網(wǎng)絡(luò)、數(shù)據(jù)結(jié)構(gòu)、操作系統(tǒng)、編譯原理等核心內(nèi)容上,浮于表面的學(xué)習(xí)很難對(duì)整個(gè)計(jì)算機(jī)科學(xué)有清晰的認(rèn)知,更難在計(jì)算機(jī)行業(yè)有所發(fā)展。

5 結(jié)語(yǔ)

(1)對(duì)于C語(yǔ)言初學(xué)者來(lái)說(shuō),寫(xiě)出各種不良或者錯(cuò)誤的代碼是很正常的,但是如果學(xué)習(xí)理念有誤區(qū),就應(yīng)當(dāng)及時(shí)糾正。有些初學(xué)者在反復(fù)糾結(jié)“a+=a-=a*a;”這種錯(cuò)誤的,意義不明的代碼,有些初學(xué)者迷戀各種似是而非的技巧,有些初學(xué)者想“學(xué)完”C語(yǔ)言(指的是,掌握所有特性)……這些都是不正確的理念,無(wú)助于培養(yǎng)計(jì)算機(jī)科學(xué)的思維習(xí)慣。

(2)C語(yǔ)言可以認(rèn)為簡(jiǎn)單,因?yàn)檎Z(yǔ)法簡(jiǎn)單,沒(méi)有像C++那么多的關(guān)鍵字和語(yǔ)法;但C語(yǔ)言也很難,語(yǔ)法簡(jiǎn)單,一些語(yǔ)義很難理解,而理解這些語(yǔ)義,不是靠背語(yǔ)法、程序代碼可以解決的。

(3)學(xué)習(xí)計(jì)算機(jī)科學(xué)需要正反饋,可以自頂層向底層和從底層向頂層相結(jié)合的方式學(xué)習(xí),而不應(yīng)該總是線(xiàn)性的,從“Hello World”到學(xué)習(xí)聯(lián)合體,函數(shù)指針這種高級(jí)特性,應(yīng)逐漸的加入操作系統(tǒng)、計(jì)算機(jī)組成原理等其他知識(shí),一步步加深一些語(yǔ)言特性的理解,同時(shí)也促進(jìn)其他理論的學(xué)習(xí)。

猜你喜歡
編譯器初學(xué)者指針
初學(xué)者,趕緊看過(guò)來(lái)
基于相異編譯器的安全計(jì)算機(jī)平臺(tái)交叉編譯環(huán)境設(shè)計(jì)
偷指針的人
為什么表的指針都按照順時(shí)針?lè)较蜣D(zhuǎn)動(dòng)
淺談如何提高初學(xué)者的鋼琴演奏能力
初學(xué)者如何臨寫(xiě)《九成宮醴泉路》
丹青少年(2017年2期)2017-02-26 09:10:56
基于改進(jìn)Hough變換和BP網(wǎng)絡(luò)的指針儀表識(shí)別
給會(huì)計(jì)初學(xué)者的幾點(diǎn)實(shí)用性建議
ARM Cortex—MO/MO+單片機(jī)的指針變量替換方法
通用NC代碼編譯器的設(shè)計(jì)與實(shí)現(xiàn)
大兴区| 海安县| 永嘉县| 龙井市| 太保市| 台江县| 永川市| 长沙县| 华亭县| 武川县| 柘城县| 额敏县| 娱乐| 阿荣旗| 青冈县| 勃利县| 泰州市| 肇源县| 同江市| 广昌县| 长乐市| 清原| 青川县| 上栗县| 阳城县| 沙坪坝区| 浦城县| 包头市| 淄博市| 会理县| 芮城县| 波密县| 鸡东县| 治县。| 阳山县| 长宁县| 那曲县| 镇远县| 红安县| 长乐市| 玛沁县|