Struct(ptr)
盧冠綸 @ sprout 2021 C/C++ 語法班
(題目照片)
Credit to : Selina
複習:struct是什麼?
(題目照片)
簡單來說,struct可以把各種不同型別的變數包成一包,
讓你可以用來一次存各式各樣的屬性。
複習:struct是什麼?
Credit to: 台大資工b07 程式電神人生勝利組 Joe Tsai 蔡銘軒軒哥
複習:pointer是什麼?
god,是一個變數,他的值是127。 (cout << god ,會印出127)
複習:pointer是什麼?
&god,是指god這個變數的位址。 (cout << &god ,會印出0xff)
*(&god),是指&god位置裡面的值。(cout << *(&god) ,會印出127)
如何宣告指標變數?
複習:pointer是什麼?
宗教戰爭:跟著型別教? 跟著變數教?
如何把指標指向別人? 如何改變指標指的地方的值?
複習:pointer是什麼?
宣告:
struct 就 struct 啊!幹嘛沒事弄成指標自找麻煩?
struct(*ptr)
今天要講的東西,就是把struct,變成指標的形式來做操作。
(就好像你把int用成*int操作一樣)
為何要struct(*ptr) ?
先用一般的struct,來看一下身分證上有哪些資訊吧!
身分證上有名字、身分證字號、生日、性別......
咦?身分證上不是還有爸爸、媽媽、配偶之類的嗎?我要怎麼加上配偶這個屬性呢?
為何要struct(*ptr) ?
所以我要怎麼加上配偶 (spouse) 這個屬性呢?
方法一(錯的):簡單!我就像下圖這樣做就好了啊!
結果...
會出這個問題,是因為電腦不知道要開多少空間一個Person。
(因為Person裡面有Person,Person裡面又有Person......)
為何要struct(*ptr) ?
所以我要怎麼加上配偶 (spouse) 這個屬性呢?
方法二(對的但不太方便):
如果我們用右圖這種寫法呢?
優點:不會吃compile error了!
缺點:如果我知道某人的配偶改名了或是變性了(X,
我必須先搜過所有人的ID,找到對應的ID之後才能改。
很花時間而且程式很不好寫。
換個方法吧!
為何要struct(*ptr) ?
缺點:很花時間而且程式很不好寫。
尤其當你遇到了兩津這種擊敗人...(X
為何要struct(*ptr) ?
所以我要怎麼加上配偶 (spouse) 這個屬性呢?
方法三(對的):最簡單快速的方法:用 struct ptr!
既不會Compile error,也不用花很多時間搜。
為何要struct(*ptr) ?
事實上,等等下半堂的linked list,也會用到這節課教的觀念哦~
(大家不用慌啦!其實就算你在這堂課矇了,我們帥帥的 Jason 講師也會幫大家再複習一遍的啦!應該吧!)
如何實作 ?
注意在.spouse這邊的東西,會是一個指標,記得不要寫錯。
如這兩張圖所示。
如何實作 ?
不過事實上,我們比較常會直接宣告struct的指標來做事情。
(例如用 *boy 和 *girl 來做事,比較少用 boy 和 girl)
這是因為這樣比較方便,而且不用煩惱要不要加&。
(而且這樣也比較好直接對位址做事情,例如底下這個例子...)
如何實作 ?
直接看一個例子比較快。
原本的寫法 新的寫法
2. boy.name 變成了 boy_ptr -> name (其他的亦然)
1. &girl 變成了 girl_ptr,&boy 變成了 boy_ptr
3. 右邊那張的大括號後面,比左邊那張的多了一個空白鍵(X
原本版 大家來找不同吧 指標版
1. &girl 變成了 girl_ptr,&boy 變成了 boy_ptr
好處:善用 boy_ptr / girl_ptr 的話,後面的程式就比較不用管 &。
如何實作 ?
boy_ptr -> name == boy.name (指摽用->,非指標用.。)
2. boy.name 變成了 boy_ptr -> name (其他的亦然)
如何實作 ?
小小複習
試著回答看看等等出現的幾個問題吧:
我現在有這麼一個struct:
角色資料:
名字:三葉
配偶:瀧
爸爸:俊樹
媽媽:二葉
小小複習
這裡創造四個指標,代表四個角色,
並且設定好這四個角色的名字及彼此的關係:
小小複習
再來,如果你是三葉(存在myself裡面),你想印出以下的東西,你要怎麼用father、mother、myself、husband這四個指標,
搭配一連串的 -> ,來印出他們呢?
例如,(我的名字)要怎麼用那些指標,搭配 -> 來表示出來呢?
小小複習
答案:(這邊一行我提供了兩組答案,這兩組都是正確的。)
函式
A:其實乍看之下好像是這樣沒錯。
不過大家在使用->的時候還是必須要記得,
->前面的東西是一個指標,而.前面的東西不是指標,
所以,指標有的特性,->前面的東西大概也會有,
所以大家還是不要把他們完全當成是一樣的東西哦!
Q:那,其實這堂課教的東西也只是把以前的struct換個寫法而已,
兩種寫法其實是完全一模一樣的...嗎?
函式
舉個例子:大家想想看底下的程式會輸出什麼:
答案:
所以,如果你已經了解兩週前的指標的課教的東西,
那struct的指標其實用類似的概念套上去就可以了。
struct ptr總結:
這堂課教了你:
1.告訴你用struct的指標會有什麼好處。
2.告訴你struct的指標的語法。
事實上,剩下的其實都是之前課程的內容或內容的延伸,
這堂課只是把以前教過的概念結合在一起,加上新語法而已,
如果有不熟的話也可以去複習以前的投影片哦~
new / delete
盧冠綸 @ sprout 2021 C/C++ 語法班
動態配置記憶體
不知道各位有沒有這樣的經驗:
題目說:測資範圍在1000以下。
我:開個大小為1000的陣列。
題目說:測資範圍在1000000以下。
我:開個大小為1000000的陣列。
題目:沒給測資範圍。
我:
動態配置記憶體
或者有沒有人想過:
題目說:測資範圍在1000000以下。
我:直接開個大小為1000000的陣列,會不會有點小浪費?
有沒有可能我開了1000000,最後卻只用到其中100?
我:有沒有方法,能夠讓我需要開多少空間,就只開多少空間,
而不會多出來呢?
你可以學習new和delete!
new
何時使用:當你需要使用到記憶體時,可以用new來跟系統借,
讓系統分配給你你要的記憶體空間。
new
例1:配置記憶體: 指標變數 = new 資料型別
例2:配置記憶體+初始化: 指標變數 = new 資料型別(初始值)
(上下兩張圖是一樣的意思。)
new
例3:配置記憶體(陣列): 指標變數 = new 資料型別[大小]
new
例4:配置記憶體 + 初始化(陣列):
指標變數 = new 資料型別[大小]{陣列內容}
new
例5:配置記憶體(struct):指標變數 = new 資料型別
new
不過,如果你的程式一直開new,一直跟系統要記憶體卻不還回去...
那可能會導致你借來的記憶體越堆越多,進而引發某些問題。
因此,我們還需要用到delete,把我們不會再用到的記憶體還回去。
delete
何時使用:當某塊借來的記憶體你不會再用到了,你想還回去的時候。
delete
例1:刪除記憶體: delete 指標名稱
例2:刪除記憶體(陣列): delete [] 指標名稱
delete
雖然在程式執行上有可能感覺沒什麼差...
不過還是希望大家養成有借有還的好習慣啦ww
自己new來的東西在用不到之後還是要記得自己delete回去。
總結
new:跟系統要記憶體。
delete:把記憶體還回去。
new 和 delete 的好處:需要多少就拿多少,比較不會
造成空間上的浪費。
struct ptr & new/delete
By allen522019
struct ptr & new/delete
- 791