激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频

什么是數組名

時(shí)間:2023-04-04 17:40:43 筆試經(jīng)驗 我要投稿
  • 相關(guān)推薦

什么是數組名

  實(shí)際上數組名永遠都不會(huì )是指針! 指針是C語(yǔ)言具有低級語(yǔ)言特征的最直接的證據。在匯編語(yǔ)言里面,指針的概念隨處可見(jiàn)。比如SP,SP寄存器又叫堆棧指針,它的值是地址,由于SP保存的是地址,并且SP的值是不斷變化的,因此可以看作一個(gè)變量,而且是一個(gè)地址變量。地址也是C語(yǔ)言指針的值,C語(yǔ)言的指針跟SP這樣的寄存器雖然不完全一樣,但原理卻是相通的。C語(yǔ)言的指針也是一種地址變量,C89明確規定,指針是一個(gè)保存對象地址的變量。這里要注意的是,指針跟地址概念的不同,指針是一種地址變量,通常也叫指針變量,統稱(chēng)指針。而地址則是地址變量的值。

  看到這里,也許你會(huì )覺(jué)得,這么簡(jiǎn)單的東西還用你來(lái)說(shuō)嗎?的確,對于p與&p來(lái)說(shuō),99%的人都能在0.1秒內脫口而出誰(shuí)是指針,誰(shuí)是地址,但是,又有多少人在使用指針的過(guò)程中能夠始終如一毫不動(dòng)搖地遵循這兩個(gè)概念呢?不少人使用指針的時(shí)候就會(huì )自覺(jué)或不自覺(jué)地把指針和地址兩個(gè)概念混淆得一塌糊涂了,數組名的濫用就是一個(gè)活生生的例子。這一點(diǎn)甚至連一些經(jīng)典著(zhù)作也沒(méi)能避免。

  不過(guò)也不能全怪你自己,筆者認為某些國內教材應該承擔最大的責任。這些教材一開(kāi)始就沒(méi)有給讀者好好地分清指針與地址的區別,相反還在講述的過(guò)程中有意無(wú)意地混用這兩個(gè)概念。更有甚者,甚至在書(shū)中明言指針就是地址!說(shuō)這話(huà)的家伙最應該在C語(yǔ)言這個(gè)地圖上抹掉,呵呵。兩個(gè)月前我在購書(shū)中心隨手翻開(kāi)了某個(gè)作者主編的一本被冠以國家“十五”規劃重點(diǎn)研究項目的書(shū),書(shū)里就是這么寫(xiě)的。當時(shí)筆者就感慨:不知道又要有多少人的思想被這家伙“性暴力”了。

  實(shí)際上,地址這個(gè)東西,本來(lái)就是一種基本數據類(lèi)型,本應該在介紹整數、浮點(diǎn)、字符等基本類(lèi)型的時(shí)候把地址顯式地放在一起討論,這樣在后面介紹指針與數組的時(shí)候就能避免許多誤解?上Р簧俳滩幕蛘吒緵](méi)有談及,或者就算提起這個(gè)類(lèi)型也用了指針類(lèi)型這個(gè)字眼。這就錯了,指針不是類(lèi)型,真正的類(lèi)型是地址,指針只是存儲地址這種數據類(lèi)型的變量!打個(gè)比方,對于

  int i=10;

  10是整數,而i是存儲整數的變量,指針就好比這個(gè)i,地址就好比那個(gè)10。指針能夠進(jìn)行加減法,原因并不是因為它是指針,加減法則不是屬于指針這種變量的,而是地址這種數據類(lèi)型的本能,正是因為地址具有加減的能力,所以才使指針作為存放地址的變量能夠進(jìn)行加減運算。這跟整數變量因為整數能夠進(jìn)行加減乘除因而它也能進(jìn)行加減乘除一個(gè)道理。

  那么數組名又應該如何理解呢?用來(lái)存放數組的區域是一塊在棧中靜態(tài)分配的內存(非static),而數組名是這塊內存的代表,它被定義為這塊內存的首地址。這就說(shuō)明了數組名是一個(gè)地址,而且,還是一個(gè)不可修改的常量,完整地說(shuō),就是一個(gè)地址常量。數組名跟枚舉常量類(lèi)似,都屬于符號常量。數組名這個(gè)符號,就代表了那塊內存的首地址。注意了!不是數組名這個(gè)符號的值是那塊內存的首地址,而是數組名這個(gè)符號本身就代表了首地址這個(gè)地址值,它就是這個(gè)地址,這就是數組名屬于符號常量的意義所在。由于數組名是一種符號常量,因此它是一個(gè)右值,而指針,作為變量,卻是一個(gè)左值,一個(gè)右值永遠都不會(huì )是左值,那么,數組名永遠都不會(huì )是指針!不管什么話(huà),只要說(shuō)數組名是一個(gè)指針的,都是錯誤的!就象把剛才int i=10例子中的10說(shuō)成是整數變量一樣,在最基本的立足點(diǎn)上就已經(jīng)完錯了。

  總之要牢牢記住,數組名是一個(gè)地址,一個(gè)符號地址常量,不是一個(gè)變量,更不是一個(gè)作為變量的指針!

  在數組名并非指針這個(gè)問(wèn)題上,通常會(huì )產(chǎn)生兩種疑問(wèn):

  1。作為形參的數組,不是會(huì )被轉換為指針嗎?

  2。如果形參是一個(gè)指針,數組名可以作為實(shí)參傳遞給那個(gè)指針,難道不是說(shuō)明了數組名是一個(gè)指針嗎?

  首先,C語(yǔ)言之所以把作為形參的數組看作指針,并非因為數組名可以轉換為指針,而是因為當初ANSI委員會(huì )制定標準的時(shí)候,從C程序的執行效率出發(fā),不主張參數傳遞時(shí)復制整個(gè)數組,而是傳遞數組的首地址,由被調函數根據這個(gè)首地址處理數組中的內容。那么誰(shuí)能承擔這種“轉換”呢?這個(gè)主體必須具有地址數據類(lèi)型,同時(shí)應該是一個(gè)變量,滿(mǎn)足這兩個(gè)條件的,非指針莫屬了。要注意的是,這種“轉換”只是一種邏輯看法上的轉換,實(shí)際當中并沒(méi)有發(fā)生這個(gè)過(guò)程,沒(méi)有任何數組實(shí)體被轉換為指針實(shí)體。另一方面,大家不要被“轉換”這個(gè)字眼給蒙蔽了,轉換并不意味著(zhù)相同,實(shí)際上,正是因為不相同才會(huì )有轉換,相同的話(huà)還轉來(lái)干嗎?這好比現在社會(huì )上有不少人“變性”,一個(gè)男人可以“轉換”為一個(gè)女人,那是不是應該認為男人跟女人是相同的?這不是笑話(huà)么。

  第二,函數參數傳遞的過(guò)程,本質(zhì)上是一種賦值過(guò)程。C89對函數調用是這樣規定的:函數調用由一個(gè)后綴表達式(稱(chēng)為函數標志符,function designator)后跟由圓括號括起來(lái)的賦值表達式列表組成,在調用函數之前,函數的每個(gè)實(shí)際參數將被復制,所有的實(shí)際參數嚴格地按值傳遞。因此,形參實(shí)際上所期望得到的東西,并不是實(shí)參本身,而是實(shí)參的值或者實(shí)參所代表的值!舉個(gè)例來(lái)說(shuō),對于一個(gè)函數聲明:

  void fun(int i);

  我們可以用一個(gè)整數變量int n作實(shí)參來(lái)調用fun,就是fun(n);當然,也正如大家所熟悉的那樣,可以用一個(gè)整數常量例如10來(lái)做實(shí)參,就是fun(10);那么,按照第二個(gè)疑問(wèn)的看法,由于形參是一個(gè)整數變量,而10可以作為實(shí)參傳遞給i,豈不就說(shuō)明10是一個(gè)整數變量嗎?這顯然是謬誤。實(shí)際上,對于形參i來(lái)說(shuō),用來(lái)聲明i的類(lèi)型說(shuō)明符int,所起的作用是用來(lái)說(shuō)明需要傳遞給i一個(gè)整數,并非要求實(shí)參也是一個(gè)整數變量,i真正所期望的,只是一個(gè)整數,僅此而已,至于實(shí)參是什么,跟i沒(méi)有任何關(guān)系,它才不管呢,只要能正確給i傳遞一個(gè)整數就OK了。當形參是指針的時(shí)候,所發(fā)生的事情跟這個(gè)是相同的。指針形參并沒(méi)有要求實(shí)參也是一個(gè)指針,它需要的是一個(gè)地址,誰(shuí)能給予它一個(gè)地址?顯然指針、地址常量和符號地址常量都能滿(mǎn)足這個(gè)要求,而數組名作為符號地址常量正是指針形參所需要的地址,這個(gè)過(guò)程就跟把一個(gè)整數賦值給一個(gè)整數變量一樣簡(jiǎn)單!

  首先我們要了解內存的分配方式。一般來(lái)說(shuō),內存的分配方式有三種:

  1.從靜態(tài)存儲區域分配。內存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內存在程序的整個(gè)運行期間都存在。例如全局變量,static變量。

  2.在棧上創(chuàng )建。在執行函數時(shí),函數內局部變量的存儲單元都可以在棧上創(chuàng )建,函數執行結束時(shí)這些存儲單元自動(dòng)被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。

  3.從堆上分配,亦稱(chēng)動(dòng)態(tài)內存分配。程序在運行的時(shí)候用malloc或new申請任意多少的內存,程序員自己負責在何時(shí)用free或釋放內存。動(dòng)態(tài)內存的生存期由我們決定,使用非常靈活,但問(wèn)題也最多。

  以上三種分配方式,我們要注意內存生命期的問(wèn)題:

  1.靜態(tài)分配的區域的生命期是整個(gè)軟件運行期,就是說(shuō)從軟件運行開(kāi)始到軟件終止退出。只有軟件終止運行后,這塊內存才會(huì )被系統回收

  2.在棧中分配的空間的生命期與這個(gè)變量所在的函數和類(lèi)相關(guān)。如果是函數中定義的局部變量,那么它的生命期就是函數被調用時(shí),如果函數運行結束,那么這塊內存就會(huì )被回收。如果是類(lèi)中的成員變量,則它的生命期與類(lèi)實(shí)例的生命期相同。

  3.在堆上分配的內存,生命期是從調用new或者malloc開(kāi)始,到調用或者free結束。如果不掉用或者free。則這塊空間必須到軟件運行結束后才能被系統回收。

  下面我們再看看,在使用內存的過(guò)程中,我們經(jīng)常發(fā)生一些什么樣的錯誤。以及我們應該采取哪些對策。

  發(fā)生內存錯誤是件非常麻煩的事情。編譯器不能自動(dòng)發(fā)現這些錯誤,通常是在程序運行時(shí)才能捕捉到。而這些錯誤大多沒(méi)有明顯的癥狀,時(shí)隱時(shí)現,增加了改錯的難度。有時(shí)用戶(hù)怒氣沖沖地把你找來(lái),程序卻沒(méi)有發(fā)生任何問(wèn)題,你一走,錯誤又發(fā)作了。

  常見(jiàn)的內存錯誤及其對策如下:

  1 內存分配未成功,卻使用了它。

  常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p是函數的參數,那么在函數的入口處用assert(p!=NULL)進(jìn)行檢查。如果是用malloc或new來(lái)申請內存,應該用if(p==NULL) 或if(p!=NULL)進(jìn)行防錯處理。

  2 內存分配雖然成功,但是尚未初始化就引用它。

  內存的缺省初值究竟是什么并沒(méi)有統一的標準,盡管有些時(shí)候為零值,我們寧可信其無(wú)不可信其有。所以無(wú)論用何種方式創(chuàng )建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。

  3 內存分配成功并且已經(jīng)初始化,但操作越過(guò)了內存的邊界。

  例如在使用數組時(shí)經(jīng)常發(fā)生下標”多1″或者”少1″的操作。特別是在for循環(huán)語(yǔ)句中,循環(huán)次數很容易搞錯,導致數組操作越界。

  4 忘記了釋放內存,造成內存泄露。

  含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開(kāi)始時(shí)系統的內存充足,你看不到錯誤。終有一次程序突然死掉,系統出現提示:內存耗盡。

  動(dòng)態(tài)內存的申請與釋放必須配對,程序中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/同理)。

  5 釋放了內存卻繼續使用它。

  有三種情況:

  (1)程序中的對象調用關(guān)系過(guò)于復雜,實(shí)在難以搞清楚某個(gè)對象究竟是否已經(jīng)釋放了內存,此時(shí)應該重新設計數據結構,從根本上解決對象管理的混亂局面。

  (2)函數的return語(yǔ)句寫(xiě)錯了,注意不要返回指向”棧內存”的”指針”或者”引用”,因為該內存在函數體結束時(shí)被自動(dòng)銷(xiāo)毀。

  條件編譯命令最常見(jiàn)的形式為:

  #ifdef 標識符

  程序段1

  #else

  程序段2

  #endif

  它的作用是:當標識符已經(jīng)被定義過(guò)(一般是用#define命令定義),則對程序段1進(jìn)行編譯,否則編譯程序段2。

  其中#else部分也可以沒(méi)有,即:

  #ifdef

  程序段1

  #endif

  這里的”程序段”可以是語(yǔ)句組,也可以是命令行。這種條件編譯可以提高C源程序的通用性。如果一個(gè)C源程序在不同計算機系統上系統上運行,而不同的計算機又有一定的差異。例如,我們有一個(gè)數據類(lèi)型,在Windows平臺中,應該使用long類(lèi)型表示,而在其他平臺應該使用float表示,這樣往往需要對源程序作必要的修改,這就降低了程序的通用性?梢杂靡韵碌臈l件編譯:

  #ifdef WINDOWS

  #define MYTYPE long

  #else

  #define MYTYPE float

  #endif

  如果在Windows上編譯程序,則可以在程序的開(kāi)始加上

  #define WINDOWS

  這樣則編譯下面的命令行:

  #define MYTYPE long

  如果在這組條件編譯命令之前曾出現以下命令行:

  #define WINDOWS 0

  則預編譯后程序中的MYTYPE都用float代替。這樣,源程序可以不必作任何修改就可以用于不同類(lèi)型的計算機系統。當然以上介紹的只是一種簡(jiǎn)單的情況,可以根據此思路設計出其它的條件編譯。

  例如,在調試程序時(shí),常常希望輸出一些所需的信息,而在調試完成后不再輸出這些信息?梢栽谠闯绦蛑胁迦胍韵碌臈l件編譯段:

  #ifdef DEBUG

  print (“device_open(%p) ”, file);

  #endif

  如果在它的前面有以下命令行:

  #define DEBUG

  則在程序運行時(shí)輸出file指針的值,以便調試分析。調試完成后只需將這個(gè)define命令行刪除即可。有人可能覺(jué)得不用條件編譯也可達此目的,即在調試時(shí)加一批printf語(yǔ)句,調試后一一將printf語(yǔ)句刪除去。的確,這是可以的。但是,當調試時(shí)加的printf語(yǔ)句比較多時(shí),修改的工作量是很大的。用條件編譯,則不必一一刪改printf語(yǔ)句,只需刪除前面的一條”#define DEBUG”命令即可,這時(shí)所有的用DEBUG作標識符的條件編譯段都使其中的printf語(yǔ)句不起作用,即起統一控制的作用,如同一個(gè)”開(kāi)關(guān)”一樣。

  有時(shí)也采用下面的形式:

  #ifndef 標識符

  程序段1

  #else

  程序段2

  #endif

  只是第一行與第一種形式不同:將”ifdef”改為”ifndef”。它的作用是:若標識符未被定義則編譯程序段1,否則編譯程序段2。這種形式與第一種形式的作用相反。

  以上兩種形式用法差不多,根據需要任選一種,視方便而定。

  還有一種形式,就是#if后面的是一個(gè)表達式,而不是一個(gè)簡(jiǎn)單的標識符:

  #if 表達式

  程序段1

  #else

  程序段2

  #endif

  它的作用是:當指定的表達式值為真(非零)時(shí)就編譯程序段1,否則編譯程序段2?梢允孪冉o定一定條件,使程序在不同的條件下執行不同的功能。

  例如:輸入一行字母字符,根據需要設置條件編譯,使之能將字母全改為大寫(xiě)輸出,或全改為小寫(xiě)字母輸出。

  #define LETTER 1

  main()

  {

  char str[20]=”C Language”,c;

  int i=0;

  while((c=str[i])!=’′){

  i++;

  #if LETTER

  if(c>=’a'&&c<=’z') c=c-32;

  #else

  if(c>=’A'&&c<=’Z') c=c+32;

  #endif

  printf(“%c”,c);

  }

  }

  運行結果為:C LANGUAGE

  現在先定義LETTER為1,這樣在預處理條件編譯命令時(shí),由于LETTER為真(非零),則對第一個(gè)if語(yǔ)句進(jìn)行編譯,運行時(shí)使小寫(xiě)字母變大寫(xiě)。如果將程序第一行改為:

  #define LETTER 0

  則在預處理時(shí),對第二個(gè)if語(yǔ)句進(jìn)行編譯處理,使大寫(xiě)字母變成小寫(xiě)字母(大寫(xiě)字母與相應的小寫(xiě)字母的ASCII代碼差32)。此時(shí)運行情況為:

  c language

  有人會(huì )問(wèn):不用條件編譯命令而直接用if語(yǔ)句也能達到要求,用條件編譯命令有什么好處呢?的確,此問(wèn)題完全可以不用條件編譯處理,但那樣做目標程序長(cháng)(因為所有語(yǔ)句都編譯),而采用條件編譯,可以減少被編譯的語(yǔ)句,從而減少目標的長(cháng)度。當條件編譯段比較多時(shí),目標程序長(cháng)度可以大大減少。

【什么是數組名】相關(guān)文章:

風(fēng)什么雨什么成語(yǔ)01-16

什么吁什么嘆的成語(yǔ)05-23

一什么就什么寫(xiě)句子10-22

什么性格開(kāi)什么店03-04

檔案是什么,有什么作用07-16

半什么半什么的成語(yǔ)03-05

山什么路什么的成語(yǔ)06-05

三什么六什么的成語(yǔ)02-10

虎什么蛇什么的成語(yǔ)11-17

什么天什么地的成語(yǔ)大全12-02

激情欧美日韩一区二区,浪货撅高贱屁股求主人调教视频,精品无码成人片一区二区98,国产高清av在线播放,色翁荡息又大又硬又粗视频