91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

web開發中為什么很多語言的數組下標是從0開始的

發布時間:2022-01-11 17:03:19 來源:億速云 閱讀:110 作者:iii 欄目:大數據

這篇文章主要講解了“web開發中為什么很多語言的數組下標是從0開始的”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“web開發中為什么很多語言的數組下標是從0開始的”吧!

數組的隨機訪問

盡管大家都知道了什么是數組,但是還是用官方的術語描述一下:數組(Array)是一種線性表數據結構。它用一組連續的內存空間,來存儲一組具有相同類型的數據。

我們可以抓住里面的幾個重點詞匯,來充分理解數組這種結構。 

1、線性表,就是數據的排列從前到后順序排列,就像一條線,像隊列、棧列表、數組等都是線性表結構。 

web開發中為什么很多語言的數組下標是從0開始的

當然有線性表結構就有非線性表結構
web開發中為什么很多語言的數組下標是從0開始的

2、連續內存空間和相同的數據類型。為啥數據訪問一個數據效率非常高?那是因為數組的定義將數組這種結構定好了規矩,線性連續給了我們快速隨機訪問的機會。但是同時也帶來了不好的地方,如果我們向其中插入或者刪除一條數據是比較費勁的。 

來看看數組是怎么實現隨機訪問的? 

假設有這么一個數組:
java int[] a = new int[10]; 
操作系統給分配了一塊連續的內存空間,假設為1000~1039,那么內存的首地址就是base_add = 1000
web開發中為什么很多語言的數組下標是從0開始的

如果你去走訪親戚,你需要知道的是什么?親戚家的地址吧(具體到門牌號),內存也一樣,我們想讀取內存里面的數據,操作系統也是通過內存的地址來訪問的,那么問題來了,內存的地址是怎么知道呢? 

這就涉及到操作系統的尋址,比如我想獲取a[2]的值,那么操作系統先會根據下面的公式計算對應內存的地址:

 a[2]的地址 = base_add + 2 * data_unit_size 

dataunitsize表示該數據類型每個元素的大小,當前是int類型為4個字節,所以算出來a[2]的地址就是1008 

那是不是可以說數組的查找的時間復雜度就是O(1)?當然不是了,正常情況下我們查找數可不是通過下標來查找的,我們是通過值來查找的,即便是二分查找時間復雜度也是O(logn)。 

刪除和插入怎么就低效了

1、插入操作
假設我們要在長度為n的數組的第k個位置插入一個數據,我們就要講第k~n的數往后挪,同理如果在最后插入就不需要挪位置,如果在第一個位置插入就要挪n個數,所以平均時間復雜度就是:(1+2+3+...+n)/n=O(n)

當然,如果不要求插入后順序還保持原來一樣,有個討巧的插入方法就是講第K個元素放到最后,將待插入的數放到第K個位置。 

舉個例子,假設數組 a[10]中存儲了如下 5 個元素:a,b,c,d,e。 

我們現在需要將元素 x 插入到第 3 個位置。我們只需要將 c 放入到 a[5],將 a[2]賦值為 x 即可。最后,數組中的元素如下:a,b,x,d,e,c。
web開發中為什么很多語言的數組下標是從0開始的

2、刪除操作

其實和插入操作是相似的,當我們對長度為n的數組的第K個數組進行刪除時,需要對后面的數據進行向前搬移操作,同理,時間復雜度和插入一樣也是O(n),這里就不詳細介紹了。

當然,在不考慮維持連續性的特殊情況下,為了提高刪除的效率,沒必要每次刪除立即進行搬移操作,不然如果連續刪除數據,就要連續進行多次的搬移。比較討巧的辦法是將待刪除的元素進行標記,實際未做刪除,等等內存不足的時候,將這些標記的數據統一進行刪除操作。這樣就會大大減少刪除操作帶來的大量數據搬移操作。 

災難!數組越界啦

對于Java來說發生數據越界的時候會拋出異常,但是對于有些語言比如C語言發生數組越界的時候并不會給你異常提示,比如下面這段代碼: 

int i = 0; int arr[3] = {0};for(;i<=3;i++) {  arr[i] = 0;  System.out.println("test");  }

顯然定義的是長度為3的數組,但是循環條件是<=,所以會訪問到數組外面的內存,而a[3]的地址剛好是存儲i的內存,所以當循環到a[3]時又賦值為0,相當于i=0;所以這個循環永遠結束不了,“hello world”會一直打印。 

所以,對于C語言來說,如果沒控制好下標,發生數組越界會出現莫名其妙的邏輯問題,還很難調試。這也是很多病毒利用數組越界來非法訪問內存來攻擊系統。 

各種容器滿天飛,還需要數組?

對于Java開發者來說,ArrayList再熟悉不過了,它為我們封裝好了各種API來操作,比使用數組方便的多,而且是支持動態擴容的,因為數組是要提前訂好大小的,當大小不滿足的時候,需要重新定義大的數組進行復制操作,這顯然很不方便,而容器類是內部有動態的分配的機制,當大小不夠的時候自動的擴容,當然這也是非常耗性能的。如果能確定數據的大小,提前指定容器的大小更好。 

那是不是意味著數組沒有存在的必要,那也不是的,比如在下面的情況: 

  • ArrayList是不能存儲基本數據類型的,需要使用他們對應的裝箱類,而拆箱和裝箱顯然都是非常耗性能的,如果特別關注性能,又需要使用基本數據類型,使用數組比使用ArrayList性能更好

  • 定義多維數組時,使用數組更加的直觀

  • 如果數據大小事先知道,而對數據的操作比較簡單。用不到ArrayList的大多API,這時候可以優先使用數組

小結:對于上層業務開發者,由于業務變化大,操作數據變化頻繁,使用容器更加方便,犧牲一點性能對系統的整體功能影響不大。但是如果是做比較偏底層的開發就需要關注性能了,性能一丁點的提升,影響也是很廣泛的,所以選擇數組比較合適。

回到主題

為什么數組從0開始呢?
從數組存儲的內存模型來看,下標比較確切的定義是“偏移”,如果用a來表示數組的首地址,那么a[0]就表示偏移為0的位置。a[x]就表示偏移x個類型大小(int 4個字節)的的位置。java a[x]_address = base_address + x * data_type_size;

但是如果從1開始計數呢,那么尋址公式就變成:
java a[x]_address = base_address + (x-1) * data_type_size;  
顯然要多運算減一的操作,對于數組數據結構的定義是偏基礎庫的,對于性能要求當然是要追求極致的,多一步和少一步運算都是非常重要的參考點,所以為了更好的性能選擇從0開始而不是從1開始。 

當然也有歷史因素,因為最早的C語言設計者使用從0開始的,所以后面的語言都延續了這一做法,這樣能減少程序員學習語言的成本。當然也有一些不是從0開始的語言,這里就不舉例了,感興趣的同學可以自行去搜索一下。 

感謝各位的閱讀,以上就是“web開發中為什么很多語言的數組下標是從0開始的”的內容了,經過本文的學習后,相信大家對web開發中為什么很多語言的數組下標是從0開始的這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桐庐县| 平定县| 原阳县| 台州市| 丰镇市| 镇江市| 子洲县| 临朐县| 天峨县| 红桥区| 遵义县| 榆社县| 益阳市| 游戏| 洪湖市| 武邑县| 禹城市| 兴义市| 高阳县| 门头沟区| 连平县| 泸定县| 峨眉山市| 玉屏| 仁怀市| 周口市| 宝丰县| 卢氏县| 灵川县| 古田县| 汝城县| 吉水县| 车险| 高唐县| 双江| 惠水县| 陆丰市| 平泉县| 塔城市| 海盐县| 什邡市|