91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

3個(gè)C語(yǔ)言編程易犯的錯(cuò)誤

Q4MP_gh_c472c21 ? 來(lái)源:嵌入式ARM ? 2019-12-03 15:47 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


典型錯(cuò)誤1:指針指向

上述代碼意圖比較明顯:定義了一個(gè)int變量a和指針變量pa,并且把a(bǔ)的地址給了指針pa。接著通過(guò)鍵入給a賦值,但運(yùn)行結(jié)果如下:

其實(shí)這個(gè)問(wèn)題是我們學(xué)習(xí)指針的時(shí)候的一個(gè)典型錯(cuò)誤了,我們知道調(diào)用scanf函數(shù)給變量賦值時(shí),賦值對(duì)象要為地址的形式,通常是加取址符“&”,但是這里采用的是*pa的格式,這里涉及的指針相關(guān)知識(shí)前面給大家講過(guò),為了更好地理解本題,就再重復(fù)一下: 對(duì)于指針來(lái)說(shuō),有己址、己值、它址、它值等特點(diǎn),己址就是指針變量本身的地址,己值就是指針變量本身地址所存放的值,也就是我們通常說(shuō)的指向的地址,這也正是它址,所以己值和它址意義是一樣的,而它值就是指針指向地址位置所存放的值。 而這里的*pa表示的意義就是它值a,那就是說(shuō)這么寫(xiě)的話下面兩行代碼是等價(jià)的:

scanf("%d", *pa);scanf("%d", a);

對(duì)比過(guò)后顯然是錯(cuò)誤的,大家一眼看出a要寫(xiě)成&a,這沒(méi)問(wèn)題。但也有人說(shuō)可以把*pa改成&pa,這樣行嗎?其實(shí)這么說(shuō)的人還是對(duì)指針中己值和己址的概念沒(méi)搞清楚,&pa表示的意義是己址,即指針變量本身的地址,就是說(shuō)你試圖用scanf修改指針變量本身地址上的值,而這個(gè)值原本是變量a的地址,其實(shí)就是在修改指針的指向!正確的寫(xiě)法應(yīng)該這樣:

scanf("%d",pa);

pa表示a的地址,即為它址,也就是&a,所以上面寫(xiě)法才與下面的等價(jià):

scanf("%d", &a);

典型錯(cuò)誤2:getchar函數(shù)

char c;while((c=getchar())!=EOF){...}
這段代碼的本意是用getchar函數(shù)讀取緩沖區(qū)字符直到結(jié)束,但是在編譯運(yùn)行時(shí),發(fā)現(xiàn)上面幾行代碼一直報(bào)錯(cuò)!邏輯上沒(méi)問(wèn)題啊,那這究竟錯(cuò)在哪里?讀者可以自己思考一下再往下看。

其實(shí)產(chǎn)生報(bào)錯(cuò)的原因有兩點(diǎn),一個(gè)是對(duì)getchar函數(shù)理解不到位,另一個(gè)是EOF的問(wèn)題。
我們首先來(lái)說(shuō)說(shuō)getchar函數(shù)的問(wèn)題,標(biāo)準(zhǔn)庫(kù)中給出了該函數(shù)的使用說(shuō)明:在它讀取一個(gè)字符后,會(huì)將其轉(zhuǎn)換為int類型返回,所以首先char c要改為int c,關(guān)于getchar的問(wèn)題還沒(méi)講完,后面還要說(shuō)。 我們接著來(lái)看看EOF的問(wèn)題,初學(xué)者對(duì)它的理解經(jīng)常會(huì)有偏差,首先它是一個(gè)宏,定義于頭文件,為-1;其次它并不是很多人理解的文件結(jié)束符,實(shí)際上它是一個(gè)標(biāo)志位,區(qū)別于其他所有字符的存在,表示一種沒(méi)有其他字符的信號(hào)。 講到這里,我們?cè)倩氐絞etchar函數(shù),由上面可以看出它的返回值必須是一個(gè)能包含所有字符的數(shù)據(jù)類型,方便它表示任意字符和EOF等標(biāo)志位。 因此,上面代碼的錯(cuò)誤就很明顯了,可能有兩種情況:1.如果編譯器中的char是有符號(hào)的且EOF被定義為-1,而恰好有字符等于0xff,那么getchar就會(huì)提前結(jié)束。當(dāng)然,如果輸入全部是7位以下的字符,那很長(zhǎng)時(shí)間不會(huì)有錯(cuò)誤。2.如果編譯器中的char是無(wú)符號(hào)的,則實(shí)際的EOF值會(huì)被截?cái)?,不再?huì)識(shí)別為EOF,將會(huì)陷入無(wú)限循環(huán)。

這里肯定會(huì)有人問(wèn)我們鍵入-1來(lái)模擬EOF跳出循環(huán)不行嗎?實(shí)際上是不行的,-1是有-和1兩個(gè)字符組成的,而getchar一次只能讀取一個(gè)字符,所以上述代碼EOF與從鍵盤(pán)輸入的字符無(wú)關(guān),那這豈不是只能死循環(huán)了?當(dāng)然不是,我們可以通過(guò)按鍵組合ctrl+d或者ctrl+z來(lái)指示結(jié)束,當(dāng)然,這里的按鍵組合輸入只是我們的一種約定,不應(yīng)該顯示檢查按鍵組合的值。

典型錯(cuò)誤3:存儲(chǔ)機(jī)制

char *p = NULL;p = "hello world";strcpy(p, "hello world");
題目很簡(jiǎn)單,就問(wèn)這段代碼寫(xiě)的有沒(méi)有問(wèn)題,如果有,問(wèn)題在哪里?

其實(shí)這個(gè)問(wèn)題如果你對(duì)C語(yǔ)言的存儲(chǔ)機(jī)制非常熟悉的話,應(yīng)該是很簡(jiǎn)單的:我們簡(jiǎn)單分析一下,第一行代碼是沒(méi)問(wèn)題的,第二行意思是讓指針p指向字符串常量,單看也沒(méi)問(wèn)題,而問(wèn)題就出在第三行了,它的意圖是對(duì)指針p指向地址的內(nèi)容進(jìn)行修改,當(dāng)然還用“hello world”只是為了增加點(diǎn)迷惑性而已。

上面說(shuō)到了C語(yǔ)言的內(nèi)存機(jī)制,其實(shí)第二行代碼過(guò)后,hello world 作為字符串常量存放于內(nèi)存中的常量區(qū),且是只讀,而此時(shí)指針p存放的是字符串常量的地址,第三行代碼企圖通過(guò)strcpy修改只讀段的內(nèi)容,因此很明顯會(huì)報(bào)錯(cuò),這也是這三行代碼的問(wèn)題所在了。

關(guān)于C的存儲(chǔ)問(wèn)題,可能有的人還不太了解,那就借這個(gè)機(jī)會(huì)簡(jiǎn)單給大家提幾句,這也是以前我寫(xiě)過(guò)的問(wèn)題:

一個(gè)編譯的C程序占用的內(nèi)存分為以下幾個(gè)部分:
1、棧區(qū)(stack)—也稱自動(dòng)類型存儲(chǔ)區(qū),由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等,例如函數(shù)調(diào)用結(jié)束后自動(dòng)釋放。

2、堆區(qū)(heap)—也稱動(dòng)態(tài)分配內(nèi)存區(qū),由程序員分配釋放,從分配到程序結(jié)束為止,若不釋放,程序結(jié)束時(shí)可能由OS回收,比如malloc分配的內(nèi)存,free釋放的內(nèi)存。
3、全局區(qū)(靜態(tài)區(qū))(static)—全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域,程序結(jié)束后由系統(tǒng)釋放。

4、文字常量區(qū)—常量字符串放在這里,程序結(jié)束后由系統(tǒng)釋放。

5、程序代碼區(qū)—編譯后的程序代碼放在這里。 來(lái)看一個(gè)具體的C程序

怎么樣?問(wèn)題雖然簡(jiǎn)單,但也給我們以后寫(xiě)代碼提了個(gè)醒,這種不易察覺(jué)的錯(cuò)誤大家一定要小心再小心,盡量避免,就說(shuō)到這里吧,感謝大家耐心閱讀!
-END-

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7645

    瀏覽量

    145849
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4419

    瀏覽量

    67661

原文標(biāo)題:3個(gè)C語(yǔ)言編程易犯的錯(cuò)誤:也許你也犯過(guò)(附代碼)

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語(yǔ)言C++的區(qū)別及聯(lián)系

    創(chuàng)建源文件時(shí)什么都不給,默認(rèn)是.cpp。 3、返回值 C語(yǔ)言中,如果一個(gè)函數(shù)沒(méi)有指定返回值類型,默認(rèn)返回int類型;C++中,如果一
    發(fā)表于 12-24 07:23

    C語(yǔ)言C++之間的區(qū)別是什么

    ,尤其是在涉及到類型轉(zhuǎn)換時(shí),會(huì)盡量防止隱式的、可能導(dǎo)致問(wèn)題的類型轉(zhuǎn)換。 相比之下,C語(yǔ)言允許更多的靈活性,但也更容易產(chǎn)生類型相關(guān)的運(yùn)行時(shí)錯(cuò)誤,因?yàn)槠漕愋蜋z查不如C++嚴(yán)格。
    發(fā)表于 12-11 06:23

    單片機(jī)C語(yǔ)言編程的心得

    寫(xiě)這個(gè)8*8按鍵程序的過(guò)程中,不管是在自己寫(xiě)還是參考別人程序的過(guò)程中,發(fā)現(xiàn)自己對(duì)C語(yǔ)言有些基本知識(shí)點(diǎn)和編程規(guī)范有很多不懂的地方,有些是自己以前的編程習(xí)慣不好,有些就是基礎(chǔ)知識(shí)不扎實(shí)的表
    發(fā)表于 12-08 07:44

    C語(yǔ)言中除數(shù)為0屬于什么錯(cuò)誤

    0 的錯(cuò)誤,以及援引數(shù)組元素時(shí)下標(biāo)溢出等。 靜態(tài)錯(cuò)誤又可以分為語(yǔ)法錯(cuò)誤和靜態(tài)語(yǔ)義錯(cuò)誤。語(yǔ)法錯(cuò)誤指有關(guān)語(yǔ)
    發(fā)表于 12-08 06:38

    為什么單片機(jī)還在用C語(yǔ)言編程?

    說(shuō)起單片機(jī)我們就會(huì)想到C語(yǔ)言,單片機(jī)為什么還在用C語(yǔ)言編程?現(xiàn)在有很多很好用的高級(jí)語(yǔ)言,如VC、
    發(fā)表于 11-28 07:37

    C語(yǔ)言編程技巧

    個(gè)成員是一個(gè)未知大小的數(shù)組,適用于動(dòng)態(tài)分配內(nèi)存并關(guān)聯(lián)一個(gè)可變長(zhǎng)度的數(shù)組。? ?3、匿名結(jié)構(gòu)體和聯(lián)合體?:C
    發(fā)表于 11-27 06:46

    C語(yǔ)言和單片機(jī)C語(yǔ)言有什么差異

    區(qū)別是由編譯器決的,只能參考對(duì)應(yīng)的編譯手冊(cè),即使同種平臺(tái)不同的編譯器對(duì)C的擴(kuò)展也有不同。 3、單片機(jī)c語(yǔ)言編程是基于
    發(fā)表于 11-14 07:55

    一文了解Mojo編程語(yǔ)言

    Mojo 是一種由 Modular AI 公司開(kāi)發(fā)的編程語(yǔ)言,旨在將 Python 的易用性與 C 語(yǔ)言的高性能相結(jié)合,特別適合人工智能(AI)、高性能計(jì)算(HPC)和系統(tǒng)級(jí)
    發(fā)表于 11-07 05:59

    第4章 C語(yǔ)言基礎(chǔ)以及流水燈的實(shí)現(xiàn)(4.3 4.4)

    的符號(hào)分別是:+、-、*、/、%。 C語(yǔ)言有一個(gè)很重要的賦值運(yùn)算符“=”,前邊程序有使用過(guò)。在C語(yǔ)言里,“=”代表的意思是賦值,而不是等于。
    的頭像 發(fā)表于 10-29 15:30 ?363次閱讀

    避雷!樹(shù)莓派初學(xué)者常犯的5個(gè)錯(cuò)誤!

    如果你剛剛?cè)胧謽?shù)莓派,你就會(huì)知道它潛力無(wú)窮,幾乎能實(shí)現(xiàn)你想到的任何功能。然而,這種自由也讓你可能在不知不覺(jué)中做出對(duì)系統(tǒng)有害的操作。在本文中,我將介紹要避免哪些錯(cuò)誤。初學(xué)者最常犯的錯(cuò)誤包括:損壞SD
    的頭像 發(fā)表于 07-22 17:16 ?1395次閱讀
    避雷!樹(shù)莓派初學(xué)者常犯的5<b class='flag-5'>個(gè)</b><b class='flag-5'>錯(cuò)誤</b>!

    深入理解C語(yǔ)言:函數(shù)—編程中的“積木塊”藝術(shù)

    編程的世界里,函數(shù)就像建筑中的“積木塊”——它們是構(gòu)建復(fù)雜程序的基石。通過(guò)靈活組合這些模塊,開(kāi)發(fā)者能打造出功能強(qiáng)大且結(jié)構(gòu)清晰的代碼。函數(shù)之所以成為C語(yǔ)言的核心,正是因?yàn)樗鉀Q了編程
    的頭像 發(fā)表于 06-30 17:26 ?1948次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>:函數(shù)—<b class='flag-5'>編程</b>中的“積木塊”藝術(shù)

    單片機(jī)c語(yǔ)言編程實(shí)例大全

    單片機(jī)c語(yǔ)言編程實(shí)例大全_18
    發(fā)表于 04-30 16:11 ?7次下載

    深入理解C語(yǔ)言C語(yǔ)言循環(huán)控制

    C語(yǔ)言編程中,循環(huán)結(jié)構(gòu)是至關(guān)重要的,它可以讓程序重復(fù)執(zhí)行特定的代碼塊,從而提高編程效率。然而,為了避免程序進(jìn)入無(wú)限循環(huán),C
    的頭像 發(fā)表于 04-29 18:49 ?2100次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>:<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>循環(huán)控制

    在工業(yè)自動(dòng)化中使用固態(tài)繼電器時(shí)應(yīng)避免的5個(gè)錯(cuò)誤

    固態(tài)繼電器(SSR)已成為工業(yè)自動(dòng)化的無(wú)名英雄。它們安靜、可靠、速度快——這是繼電器應(yīng)具備的所有特點(diǎn)。但就像高科技駕駛艙中的新手飛行員一樣,即使是經(jīng)驗(yàn)豐富的工程師在使用SSR時(shí)也會(huì)常見(jiàn)錯(cuò)誤。本文讓我們來(lái)看看應(yīng)如何避免在工業(yè)自動(dòng)化中使用固態(tài)繼電器時(shí)應(yīng)避免的5
    的頭像 發(fā)表于 04-20 11:42 ?783次閱讀

    如何在 樹(shù)莓派 上編寫(xiě)和運(yùn)行 C 語(yǔ)言程序?

    在本教程中,我將討論C編程語(yǔ)言是什么,C編程的用途,以及如何在RaspberryPi上編寫(xiě)和運(yùn)行C
    的頭像 發(fā)表于 03-25 09:28 ?1213次閱讀
    如何在 樹(shù)莓派 上編寫(xiě)和運(yùn)行 <b class='flag-5'>C</b> <b class='flag-5'>語(yǔ)言</b>程序?