如果你覺得社課還算輕鬆,這裡提供你一些額外的補充教材。
這些是我們在備課的時候覺得稍微進階,或是篇幅太多,而沒有放在正式社課的內容。
這邊有目錄,左邊也有,可以跳到自己想看的地方
建議必看的地方 :
我們知道陣列必須在宣告時就指定範圍,可是當不知道大小時就很頭痛。
這時候就要用到動態宣告。
裡面的變數只能是整數(滿合理因為沒有"小數個東西"),
而且在舊的 C++ 中不支援這種使用方式。
當時只能使用像是 Array 或是 Vector(之後會教) 之類的資料結構實現。
陣列的遍歷指的是針對陣列的每一項進行動作,也就是走過整個陣列。
雖然現在的陣列都能通過變數的形式得知長度,但之後可能會遇到能夠擴充的陣列,這時候就要使用這些方法遍歷陣列。
不過,sizeof函數不能判斷當成資料傳入函數中的陣列,也就是說,它必須要和陣列的宣告位置處在同一函數中(例如:main函數。
所以,像是std::vector或std::array都有內建回傳陣列長度的函數,盡量用那些函數取得長度。
除此之外,c也有其他的方式遍歷陣列,不過都要求比較新的c版本(雖然也沒有多新。
警告:以下提到的觀念牽扯到指標,非相關人員請立即撤離
你是否有想過為什麼 int,char,bool ,甚至連不是保留字的 std::string 都有陣列?
這是因為陣列不是一種資料型態,他是一種函式。
所謂陣列,是在宣告時替變數拉長他的空間,好放下更多同類型的資料。
也就是說 int a[2] 的大小會比 int a大兩倍
你可能有注意到我在 sizeof() 中的 a 後面並沒有中括號,很明顯不符合之前說的陣列使用。
其實不盡然,所以我們接下來就要談談中括號的意義是什麼,以及它為什麼從0開始。
先說說陣列長什麼樣子,
以上面的a[2]為例:
記憶體位置 | 0 | 1 |
---|---|---|
對應到的變數 | a[0] | a[1] |
指標的表示 | a | a+1 |
雖然實際上的記憶體位置不會那麼剛好從 開始,但他們確實會連在一起。
對不知道指標是什麼的人先簡單說明一下:
指標宣告時並不會像變數一樣被分配空間,但是他們可以被指定位置。
也就是說,除了以變數的方式儲存資料,我們也可以用指標指向一塊地方後存資料。
但是,既然指標一開始不會被分配空間,那要怎麼使用?
這裡其實有兩種方式,但我們這邊只提到第二種,也就是陣列。
複習一下a[2]的模樣:
記憶體位置 | 0 | 1 |
---|---|---|
對應到的變數 | a[0] | a[1] |
指標的表示 | a | a+1 |
沒錯,陣列在宣告時會創建和變數同名的指標,之後給它分配空間。
而因為空間是連在一起的,所以沒有必要再創立一個指標,只要用原本的指標呼叫即可。
也就是說
你可能會發現,a[1] 的呼叫方式剛好就是 *(a+1)。
沒錯,中括號內加的數字就是指標後幾格(宣告時例外,指的是要多少項)。
那你有沒有想過, a[-1] 會發生什麼?會是錯誤嗎?
試試這個:
當嘗試調出未初始化的記憶體空間時,它會回傳一個亂碼,
這也是為什麼會輸出亂碼的原因。
這裡其實在之前的補充講義有稍微的提到,在const那邊
我現在要給你五個數字,請把他們依據除以3的餘數分類,
並輸出餘數分別為0,1,2的數量。
用if寫:
雖然這題並不困難,但總覺得很麻煩不是嗎?
試試不用if寫寫看吧,你可能會想:這怎麼可能?
答案是可能的喔
沒錯,中括號內的值不一定要是常數,所以可以用這種方式寫。
既然在之前有提到任何資料型態都有陣列,那有沒有陣列的陣列?
有,這被叫做二維陣列。
使用方式:
為什麼會長這樣呢?
如果我們用大括號表示陣列
那這就是二維陣列的樣子
也就是說,a的前面中括號指的是裡面有幾個一維陣列,
而第二個中括號則是每個一維陣列內有幾項。
所以也可以用這樣的方式表示(以a[2][2]當示範)
陣列\內容 | 第一項 | 第二項 |
---|---|---|
第一個陣列 | 1 | 2 |
第二個陣列 | 3 | 4 |
所以,第二項是a[0][1],而第三項是a[1][0]
其實還有三維、四維等陣列,概念和二維陣列是相同的。
而至於他們的組成……
你有聽過…指標的指標嗎?