作者game0416 (鳳狼)
看板NTUE-CS102
標題Re: [閒聊] 程設作業
時間Wed Mar 10 00:05:49 2010
首先我要更正一下上次最後一頁的code
沒注意到用指標動態宣告時要用
->,那整頁都是
.當成員存取運算子
非常抱歉<(_ _)>
今天的內容是
封裝、鏈結串列
然後因為我中間好像不小心睡掉一段說明
所以我不知道王老大用了些什麼說明hmm
一樣是盡量寫簡單看看Orz
這邊提醒一下,作業內容如作業1的意思應該是
作業1 建立類別(陣列) -> 輸入資料 -> 排序 -> 輸出
變成作業3 建立類別(鏈結串列) -> 輸入資料 -> 輸出
--
封裝這部份上次第七第八頁大概提過一點用法
最主要是說,變數不由
類別之外直接存取
原始用意是避免設計上的疏失、容易debug兩點為多
: 嗯...講是這樣講,不過也有
: 「會寫錯的人就是會錯,不會寫錯的人就是不會寫錯」by 強者我朋友 這樣的說法hmm
回顧一下上週寫的
類別有分
public跟
private兩部份
前者就像是全域變數,在任何一個有宣告該類別的函式都可以修改
後者就像區域變數,只能在類別之內修改
簡單寫一小段code比較
class C{
public:
int a;
private:
int b;
};
--
如果我們宣告了一個C test;
並且試著編譯以下兩行程式碼
test.a=
5;
test.b=
6;
編譯器將不會通過,並告知b是private
: 警告訊息如右: 'int C::b' is private
這就是不能從類別外部直接改變的意思
所以我們要在類別
內宣告函式,藉由函式去改變類別內的數值
以上面的範例做修改,應該就是寫成這樣
class C{
public:
void setb(
int B) {b=B};
private:
int b;
};
--
函式內使用類別,要修改類別C裏頭,b的內容時
就改成這樣寫
C.setb(
6);
像這樣,以類別裏面的函式setb()去設定類別中
int b的內容
就是將變數"封裝"在類別中,不讓外面的人可以直接碰
: 突然有種哪家精品店的感覺...「架上商品請勿觸碰,如有需要請洽櫃檯人員」(?)
感覺很像當初在講函式怎麼用一樣,會有種多此一舉的感覺
不過類別這種東西一多還是會亂,保守還是請用函式修改這樣
這邊順便提一下,宣告類別內的函式一行可以像範例那樣縮在一起就算了
如果不是只有一行,那最好是像下頁這樣寫在類別之外會好一些
湊 個 字 在 這 裏 比 較 好 看
--
class aclass{
public:
void seta_and_couta(
int A);
private:
int a;
};
// 此之上是類別,此之下是敘述類別內函式內容
void C::seta_and_couta (
intA){
a=A;
cout <<a;
}
int main(){
int a;
aclass ex;
cin >>a;
ex.seta_and_couta(a);
}
完整寫一串大概是長這樣子,順便附上前面說明中的完整範例一套於下頁QQ
--
class aclass{
public:
int a;
void setb(
int B) {b=B;};
int getb() {
return b;};
private:
int b;
};
int main(){
aclass test;
test.a=
5;
test.setb(
6);
cout <<test.a <<' '<<test.getb();
}
這邊可以回憶一下我最後這個cout是怎麼做到的
再來鏈結串列會用到。
--
被我忘記的作業二...
要寫成封裝,所以多加兩個函式小改就好
因為前面說明很多了,只寫一部份Q 總之就是拿函式去動變數
class aclass{
public:
void setid(
int ID) {b=ID;};
int getid() {
return id;};
private:
int id;
};
int main(){
aclass students[
10];
for (
int i=
0;i<
10;i++){
int id;
cin >> id;
students[i].setid(id);
}
for (
int i=
0;i<
10;i++)
cout <<students[i].getid() <<endl;
}
--
hmm
封裝這樣講好像很亂,不過好像也只能這樣講Orz
概念性質東西很討厭是要知道當事人問題在哪
所以概括性的說明不容易解釋
有問題真的請多問QQ
再來是意味不明的鏈結串列
: 欸,資結不是二年級的課嗎...
這邊要再提醒一下作業內容不用排序
可以少思考很多很多東西(遠目)
鏈結串列(linked list)
近似於一種鐵鍊式的方法去把數個獨立的物件(鐵環)接串在一起
在思緒中如同一串鏈子的構造....
: 他媽的誰看的懂上面這兩句!
以我自己的理解觀來說
我會把鏈結串列想成是火車那樣的關係
車廂是物件,連結器是指標
--
大概會像是
███ ←這是車廂 _↙這東西是連結器
███__███__███__███__███__
藉由一個連結器,讓我可以從第一節車廂,移動到第二節車廂這樣
以此做出兩個物件之間的"關係"
: 概念上是這樣...在記憶體位址上有點蟲洞的感覺
嗯...我是code派,有點概念就硬凹code出來
或是看完code就能搞懂構造,所以我在這之後就直接code說明了Orz
要做出連結的構造,使用的是指標去指向下一節車廂的位址
然後呢,這個部份要內嵌在車廂裡面的一部分
下頁這段
class會有比較完整的說明
然後一邊去做這次的作業內容
--
先假設我們只要輸入id就好,一次要求多了我怕太花版面
所以我們先建立一個能輸出入id的類別內容
class aclass{
public:
void setid(
int ID) {id=ID;};
int getid() {
return id;};
private:
int id;
};
在這之後,加入指標部分的輸出入
class aclass{
public:
void setid(
int ID) {id=ID;};
int getid() {
return id;};
void setptr(aclass *PTR) {ptr=PTR;};
aclass
* getptr(){
return ptr;};
private:
int id;
aclass *ptr;
};
--
請特別注意那個*
因為我們要回傳的是一個指標,而不是物件
所以那個*絕對不能遺漏了,不然後面會出問題的
寫完類別的構造...再來進入main裏頭去實做、宣告類別開始運作
這裡我會寫成正常的佇列...把先宣告的視為頭去運作
而不是像老師的範例寫成視為尾端(堆疊)
: 佇列與堆疊就是先進先出與先進後出...詳細以後再談,不然就拿這兩個名詞去google
首先,使用動態宣告去產生一個物件
然後,用"兩個"指標去儲存這第一個物件的位址
一個用來當在車廂間穿梭的"人",一個用來記錄第一個車廂的位置
就像這裡這兩行一樣的宣告
int main(){
aclass *node,*head; //node當人,head當第一節車廂
head = node =
new aclass;
}
--
再來,再加入輸入與創造的部份
這裡我選擇在輸入完之後,同時創造下一個鏈結的位址
並讓人走到下一間車廂
int main(){
aclass *node,*head; //node當人,head當第一節車廂
head = node =
new aclass;
for (
int i=
0;i<
10;i++){
int id;
cin >>id;
node->setid(id);
if (i!=
9){
node->setptr(
new aclass);
node = node->getptr();
}
else {
delete node->getptr();
node->setptr(NULL);
}
}
}
--
其中
node->setptr(
new aclass);
node = node->setptr(
new aclass);
兩行,是製造下一節車廂(下一個物件),並且將這一個位址放在這節車廂的指標上引導
至於那個if,只是單純我沒想到好方法
所以用土法煉鋼的方法寫遇到最後一個的時候怎樣處理..
就只是砍掉多生出來的那個,然後把NULL塞進去指標當串列結尾
寫到這邊應該是串列形成、輸入資料過程寫完
再來只要輸出就好
: 我會建議自己重寫一份形成、輸入分開的,多練習是好事QQ
輸出部分,首先要把node歸零,回到第一節車廂,再逐個輸出內容..
所以開頭第一句是
node = head
--
先來寫個輸出,因為有串列第一項,與最末尾的記號,因此使用whlie會好一點
輸出應該不是問題
node = head;
while (
1){
cout <<node->getid <<endl;
}
問題來自於往下走要怎麼寫...還有思維有沒有亂(毆)
node = head;
while (
1){
cout <<node->getid() <<endl;
if (node->getptr() != NULL)
node = node->getptr();
else break;
}
這裡就是只要分辨是不是最末項就ok了
輸出應該不是太大的問題hmm
--
最後,出於習慣,還是要記得
delete掉生出來的東西
node = head;
while (
1){
if (node->getptr() != NULL){
aclass *tmp=node;
node = node->getptr();
delete tmp;
}
else{
delete node;
break;
}
}
--
...整個內容大概是這樣吧
這次在發文前有記得編一次,應該沒有太大的bug(死)
有問題多問看看,比較能找到方法去解釋問題(倒)
另外,根據慣用的寫法,就算是class內建private屬性
還是會逐行由public開始定義,然後是private、protected
--
紅白本命
○楽園の巫女
博麗 霊夢 職業:博麗神社の巫女さん
Hakurei Reimu 能力:主に空を飛ぶ程度の能力
@東方project系列
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 58.114.76.199
推 dosomethnig:頭推 03/10 00:06
推 Arashinoon:肩推 03/10 00:07
※ 編輯: game0416 來自: 58.114.76.199 (03/10 00:16)
推 CaptainWill:屌推 03/10 00:07
推 godhand0629:穴推 03/10 00:09
推 j2612280:推他x的= =鏈結明明就是大二的課= = 03/10 00:11
推 Tuko: 弓推 03/10 00:11
推 CaptainWill:囧 03/10 00:11
推 godhand0629:老師交太簡單就說人家笑話 太難就說大二的客 安邦不是 03/10 00:12
→ godhand0629:我要講你... 03/10 00:12
推 joe989879:用力推.....推倒__ 03/10 00:13
推 j2612280:靠= =服部...你自己說..明天你要死幾次!!!! 03/10 00:14
推 pig456654:= = 安邦 不要欺負人0.0 03/10 00:14
→ pig456654:難道你只有肉嗎? 03/10 00:15
推 Arashinoon:安邦什麼人你們還不知道 我就不多說了 鳳狼大必推 03/10 00:15
推 pk873:這學期就靠你了 (誤) 03/10 00:26
噓 dosomethnig:純噓安邦無能 當公關沒聯誼! 樓下幫我推回來 03/10 00:27
推 Arashinoon:我幫你 03/10 00:28
→ j2612280:靠= =峻毅狗!! 03/10 00:34
推 CaptainWill:你看看阿幹做得多好 03/10 00:35
推 t60702:推- - 03/15 20:41