作者 主題: array 注意地方  (閱讀 7165 次)

0 會員 與 1 訪客 正在閱讀本文。

vicent

  • 懷疑的國中生
  • **
  • 文章數: 33
    • 檢視個人資料
array 注意地方
« 於: 2003-05-31 08:55 »
將我寫程式發現的一些心得得大家分享...
-----------------------------------------------------

如果要利用副程式來做call by address時,
不能將”陣列位址”當作函式參數傳給副程式,
正確的做法,應該是設定一個pointer,指向這個陣列的起始位址(亦即該陣列名稱),

然後再利用這個新設定的指標,當作函數的參數,將它傳給副程式,來做各函數間位址(address)參數的傳遞,
以達到call by address的功用
-----------------------------------------------------

**這裡需要注意的是,當我們宣告一個陣列的時候,這個陣列的名稱是一個位址,指向該陣列的第0個單位,但是其型別為常數(const),亦即不能改變
ex.
char buf[10];

則buf == &buf[0],
但是 buf其實真正的型別為

const char* buf;  <----*** 非常重要 ***


範例...
--------------------------------------------------------------
char bufRecvfromMn[MAXPKTSIZE];
char bufRecvfromRa[MAXPKTSIZE];
unsigned int lenRecvBuf;
unsigned int idxSelApRecd;


//原始程式做法
if ( ReadfromMn(sockfdMn, bufRecvfromMn, &lenRecvBuf) == TRUE )
   {
         if ( SendPkt2Ra( sockfdRaw, idxSelApRecd, bufRecvfromMn, &lenRecvBuf) == TRUE )
^^^^^^^^^^這樣的call by address會有問題
      .....
   }


//修改後的程式做法
//--------------------------------------------------------------
//上面的bufRecvfromMn的寫法會有問題,
//正確的寫法為
char *ptrRecvfromMnBuf = bufRecvfromMn;
if ( ReadfromMn(sockfdMn, *ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
   if ( SendPkt2Ra( sockfdRaw, idxSelApRecd, *ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
          ......
   }


//經過這樣的修改,副程式ReadfromMn對ptrRecvfromMnBuf的變動,
//才能return反應給呼叫它的函式ReadfromMn
//--------------------------------------------------------------
BOOL
ReadfromMn( sockfdMn, ptrRecvfromMnBuf, ptrRecvBufLen)
int sockfdMn;
char *ptrRecvfromMnBuf;
int ptrRecvBufLen;
   .....

梁楓

  • 俺是博士!
  • *****
  • 文章數: 6220
    • 檢視個人資料
array 注意地方
« 回覆 #1 於: 2003-05-31 12:20 »
要不要註明一下,是什麼程式語言呢?

osdai

  • 可愛的小學生
  • *
  • 文章數: 12
    • 檢視個人資料
array 注意地方
« 回覆 #2 於: 2003-05-31 14:35 »
你的 "修改後的程式" 是不是寫錯了?
你在ReadFromMm裡把ptrRecvfromMnBuf定義為char *,可是你在"修
改後的程式"裡把ptrRecvfromMnBuf 解參考了,這樣傳到函數裡的值應
該是bufRecvfromMn[0]的內容?

還有看不出你 "原始程式做法 "那裡有錯,大概會有警告而以吧!
不然把bufRecvfromMn改成&bufRecvfromMn[0]就對會有問題了!
再不把bufRecvfromMn改成(char *)bufRecvfromMn該也是可以的

AD

  • 懷疑的國中生
  • **
  • 文章數: 38
    • 檢視個人資料
array 注意地方
« 回覆 #3 於: 2003-05-31 19:51 »
char buf[10];

buf 的型別仍然應該是 char* 吧

char *a = "const";

a 的型別才是 const char*

vicent

  • 懷疑的國中生
  • **
  • 文章數: 33
    • 檢視個人資料
array 注意地方
« 回覆 #4 於: 2003-06-01 21:49 »
引述: "梁楓"
要不要註明一下,是什麼程式語言呢?

Linux下的C語言,compiler為gcc

vicent

  • 懷疑的國中生
  • **
  • 文章數: 33
    • 檢視個人資料
Re: array 注意地方
« 回覆 #5 於: 2003-06-01 22:05 »
引述: "vicent"

//修改後的程式做法
//--------------------------------------------------------------
//上面的bufRecvfromMn的寫法會有問題,
//正確的寫法為
char *ptrRecvfromMnBuf = bufRecvfromMn;
if ( ReadfromMn(sockfdMn, *ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
   if ( SendPkt2Ra( sockfdRaw, idxSelApRecd, *ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
          ......
   }


ㄆㄞ厶ㄟ啦
應該為
char *ptrRecvfromMnBuf = bufRecvfromMn;
if ( ReadfromMn(sockfdMn, ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
   if ( SendPkt2Ra( sockfdRaw, idxSelApRecd, ptrRecvfromMnBuf, &lenRecvBuf) == TRUE )
          ......
   }
才對,
另外發現單就程式正確性而言,
原始程式的做法應該也沒有問題,
若在副程式中,只有修改array的內容,而沒有動到&array[0]的值,
則原始程式的做法也是可以的...

vicent

  • 懷疑的國中生
  • **
  • 文章數: 33
    • 檢視個人資料
array 注意地方
« 回覆 #6 於: 2003-06-01 22:08 »
引述: "AD"
char buf[10];

buf 的型別仍然應該是 char* 吧

char *a = "const";

a 的型別才是 const char*


為什麼
char *a = "const";

a 的型別才是 const char* ??
不懂,
是不是所有在宣告時,有指定(assign)值的變數,其位址都為static?

AD

  • 懷疑的國中生
  • **
  • 文章數: 38
    • 檢視個人資料
array 注意地方
« 回覆 #7 於: 2003-06-04 18:49 »
像 "const" 用雙引號所圍起來的字元(s)叫做 string literal

在新的標準中,它所代表的是 const char 所組成的 array

compiler 提供如下的隱式轉換是為了要和過去的程式碼相容
代碼: [選擇]

char *str = "const";

但是在gcc3.2.2中,如果我接下來作出設值的動作
代碼: [選擇]

str[1] = 'a';

compile可以通過,不過在執行時就會請我吃segmentation fault

(另外在bc++5.6我也做了這樣的測試,結果是沒有問題的 :o )

vicent

  • 懷疑的國中生
  • **
  • 文章數: 33
    • 檢視個人資料
array 注意地方
« 回覆 #8 於: 2003-06-05 08:57 »
另外關於array值設定上,我有一個疑問
ex.
unsigned char buf[100];

bzero( buf, 100);

//要將buf的內容設定為"Hello World"
buf="Hello World";     ==> 請問這樣可以嗎?

會不會造成在compile可以通過,
但是在執行時會請我吃segmentation fault  :)

還是利用
memcpy( buf, "Hello World", strlen("Hello World");
這樣才不會有問題?? :roll:

AD

  • 懷疑的國中生
  • **
  • 文章數: 38
    • 檢視個人資料
array 注意地方
« 回覆 #9 於: 2003-06-06 21:52 »
唔...這個自己試一下應該不用花五分鐘吧 :wink:

其實我是學C++的,字串的處理我都直接用 std::string 解決

很少會用到指標去處理字串