全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1532
推到 Plurk!
推到 Facebook!

請問將struct傳入function改變值的問題

尚未結案
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-01-05 03:18:55 IP:163.28.xxx.xxx 未訂閱
#include  #pragma hdrstop #include #include typedef struct test { double data; test *next; }test; test *c_new,**temp; void aa(test** temp1); #pragma argsused int main(int argc, char* argv[]) { temp=new test*[5]; c_new=new test; c_new->data=4; c_new->next=NULL; temp[0]=c_new; cout<data<<"\n"; aa(temp[0]); cout<data; char temp2; temp2=getch(); return 0; } //--------------------------------------------------------------------------- void aa(test *temp1) { c_new=new test; c_new->data=789; c_new->next=NULL; temp1=c_new; } 以上是小弟我利用BCB console wizard所寫的一個測試struct的程式,我所希望的是將我所要的struct的值作改變,也就是程式碼中的temp[0],所以我利用aa這個函式來達到我要的動作,但是發現我將temp[0]送入aa這個函式之後,發現值根本沒有改變,但是我將函式改成如下: void aa(test **temp1,int i) { c_new=new test; c_new->data=789; c_new->next=NULL; temp1[i]=c_new; } 也就是要多傳一個i這個index來告知函式我要改變那個struct的值,問題就是為什麼我用前面的函式void aa(test *temp1)不能改變值,這樣跟call by address就有衝突啦,還是我對於call by address了解不夠深入,麻煩對於這個問題有了解的先進們是否可以幫我解答一下!感激不盡!!
fffhghgjh
一般會員


發表:2
回覆:33
積分:17
註冊:2004-12-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-01-05 10:55:39 IP:61.220.xxx.xxx 未訂閱
void aa(test *temp1)
{
    c_new=new test;
    c_new->data=789;
    c_new->next=NULL;
    temp1=c_new;
}
 
在這個function中 你改變的只是把temp1的指標重新指向到c_new 沒有改變到原來的指標內容
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-01-05 14:54:55 IP:163.28.xxx.xxx 未訂閱
引言:
void aa(test *temp1)
{
    c_new=new test;
    c_new->data=789;
    c_new->next=NULL;
    temp1=c_new;
}
 
在這個function中 你改變的只是把temp1的指標重新指向到c_new 沒有改變到原來的指標內容
首先感謝你的回答,我改變的地方在c_new->data原本是4傳入test之後我希望它可以變成789但是回到main之後值不變。如果如你所說的改變指標位址那應該c_new->data應該也會變成789,那怎麼還是一樣還是4呢?
fffhghgjh
一般會員


發表:2
回覆:33
積分:17
註冊:2004-12-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-01-05 15:24:38 IP:61.220.xxx.xxx 未訂閱
在aa的function中 c_new又重新分配記憶體的位置 所以會有新的指標分配給c_new 試試看把aa中的 c_new = new test; 拿掉 這樣不但c_new的值改變了 連帶temp[0]也改變了
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-01-05 20:25:46 IP:163.28.xxx.xxx 未訂閱
引言: 在aa的function中 c_new又重新分配記憶體的位置 所以會有新的指標分配給c_new 試試看把aa中的 c_new = new test; 拿掉 這樣不但c_new的值改變了 連帶temp[0]也改變了
問題就是在我一定要動態宣告一個新的struct,所以這位大大你所說的不符合小弟的要求,我發現是它出現在是在他傳給aa這個function的時候的位址根本跟temp[0]不一樣,我也不知道為啥為這樣,一定是我觀念上的問題,也就是對於call by address也許有些誤解,我又試了這個方式,如下所示:
int main(int argc, char* argv[])
{
 temp=new test*[5];
 c_new=new test;
 c_new->data=4;
 c_new->next=NULL;
 temp[0]=c_new;
 cout<data<<"\n";
 
 c_new=new test;
 c_new->data=6;
 c_new->next=NULL;
 temp[0]=c_new;
 cout<data<<"\n";
  
 aa(temp[0]);
 cout<data;
 char temp2;
 temp2=getch();
 return 0;
}
改的地方就是紅色的地方,這是小弟另外加上去的,此時的output是4 6 6,這時發現如果緊接著在重新宣告一個新的struct,在重新assign給temp[0],值會改變,偏偏如果傳到aa function就沒改變,我想知道的是 為什麼會這樣 ,我只是想了解,如果純粹只是要改變temp[0]值的做法小弟已經知道怎樣改變它的值。感謝你的回應。
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-01-05 22:30:19 IP:211.76.xxx.xxx 未訂閱
typenew你好:     我想你應該聽過Call by value和Call by reference的不同吧? 試試下面兩種不同的函式呼叫,看結果一不一樣
void aa(test* temp1)
{
    test* c_new=new test;
    c_new->data=789;
    c_new->next=NULL;
    temp1=c_new;
}    void aa(test*& temp1)
{
    test* c_new=new test;
    c_new->data=789;
    c_new->next=NULL;
    temp1=c_new;
}
 
fffhghgjh
一般會員


發表:2
回覆:33
積分:17
註冊:2004-12-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-01-07 10:48:40 IP:61.220.xxx.xxx 未訂閱
void aa(test *temp1)
{
    c_new=new test;
    c_new->data=789;
    c_new->next=NULL;
    *temp1=*c_new;
}
 
這樣利用call by address 應當達到你的要求了
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-01-08 18:58:57 IP:163.28.xxx.xxx 未訂閱
Dear fffhghgjh pwipwi: 兩位的方法都可行,非常感謝,照兩位大大的改法,那我原本的寫的根本只是call by value,這個value只是"位址",所以改變的只是在存放這個位址裡面的值,而非改變存放的位址,不知道我這樣的想法是否是正確的?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-01-09 00:49:13 IP:211.76.xxx.xxx 未訂閱
我不能確定你提的概念是否是"正確"的...(我也常常被pointer的pointer弄混)    不過以我所知道的,Cplusplus的程式強調如果可以用reference取代pointer,就用reference來做。不只可以減少可能的轉型錯誤,而且又不失效率。就算要用pointer,也都用smart pointer來包裝,好處是幾乎不可能會memory leak。    如果你試著改寫你的程式,限制都不用到"*"這個字元。 相信你一定可以再有不少的收獲~ (我也很少用到*了...,但這不代表我沒用到pointer)
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-01-09 16:06:39 IP:163.28.xxx.xxx 未訂閱
引言: 我不能確定你提的概念是否是"正確"的...(我也常常被pointer的pointer弄混) 不過以我所知道的,Cplusplus的程式強調如果可以用reference取代pointer,就用reference來做。不只可以減少可能的轉型錯誤,而且又不失效率。就算要用pointer,也都用smart pointer來包裝,好處是幾乎不可能會memory leak。 如果你試著改寫你的程式,限制都不用到"*"這個字元。 相信你一定可以再有不少的收獲~ (我也很少用到*了...,但這不代表我沒用到pointer) < face="Verdana, Arial, Helvetica"> Dear fffhghgjh pwipwi: 此問題辛苦兩位的解答,但是分數只能給一位,小弟只好給最先回答的pwipwi,請fffhghg見諒。 此外,想請教pwipwi,最後你說限制不要用到"*"這個字元,小弟想想我會用到的地方,1:動態宣告陣列,2:傳指標給函式,3:乘號(這應該不能省吧= ="),所以能省的地方應該是2吧,也就是利用"&"來做到Alias,也可以達到傳指標的目的,不知道pwipwi大大所說的盡量不要用的地方是不是指這個?不過在小弟的問題中,解法為void aa(test*& temp1)那個"*"字元好像不能省略吧,還是有其他方式可以省略而且可以達到改變的效果?
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-01-09 19:26:11 IP:211.76.xxx.xxx 未訂閱
三個都有省的方法,而且還有不少好處,    第一個可以用STL中的vector來做到,而且還可以做得很出色。以你的例子來說  
 
#include 
using namespace std;    int main(void)
{
vector array_of_test(5); //宣告一個test的array,大小為5
array_of_test[0].data = 4;
array_of_test[0].next = NULL;
}
這個array還可以用resize來動態改變大小: array_of_test.resize(10); 而且還會自動釋放配置的記憶體。 第二個除了refrence以外,還有一個手法是用auto_ptr包裝一個pointer ,相關的內容我之前在站上提過。auto_ptr是C加加標準的一員,查bcb的help或在站上用auto_ptr應該都可以找到相關的討論。 第三個乘號在程式中也是能省就省,對效率會提昇很多。不過有時選是視compiler而定...。 比如: unsigned int value = 1000; value *= 2; 我會改成 value <<= 1; 如果是value *= 3; 我會改成 value = (value << 1) value; 改完後唯一的缺點是後來的人維護會比較麻煩,因此我只在速度很吃緊的程式碼中使用。並且加上註解,...不然自已以後可能也會看不懂
typenew
一般會員


發表:8
回覆:17
積分:5
註冊:2004-03-26

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-01-11 20:13:19 IP:163.28.xxx.xxx 未訂閱
聽君一席話,勝讀萬卷書 除了第一個使用vector以外,我從來沒想過這樣做可以改進performance,未來小弟在code時候也利用這些方法來試試。感恩啦
系統時間:2024-06-28 18:37:41
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!