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

請教一個結構中的不定長度陣列的sizeof問題

答題得分者是:syntax
vincechang
一般會員


發表:2
回覆:1
積分:0
註冊:2010-06-22

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-06-23 00:28:50 IP:118.160.xxx.xxx 訂閱
以下內容皆在同一個file中
[code cpp]
typedef unsigned char BYTE;
typedef struct
{
BYTE p[2];
BYTE q[];
} _STRUCT1;

_STRUCT1 gObj ={{1,2},{3,4}};//declaration and definition

BYTE r[]={5,6};//declaration and definition

void Function1(void)
{
BYTE m;
m = sizeof(gObj.p);//ok 沒問題
m = sizeof(gObj.q);//compile err = invalid application of 'sizeof' to incomplete type 'BYTE[]'
m = gObj.q[0];//ok 沒問題
m = gObj.q[1];//ok 沒問題
m = sizeof(r);//ok 沒問題
m = r[0];//ok 沒問題
m = r[1];//ok 沒問題
}
[/code]

實驗可知gObj.q[0],gObj.q[1]可以正確讀出,
表示這樣的結構中的陣列的宣告與
定義(初始化)沒有問題
但是這樣的寫法會產生compile err(第16行),
所以有一些疑問想要請教:

Q1. compile err的部份:我雖然在結構的宣告中並沒有指明q的長度,但是緊接著就進行結構變數gObj的定義,compiler難道看不出它已經是一個"complete type"的宣告了嗎?

Q2. 為什麼單一陣列用相同的方式進行宣告,sizeof卻沒有問題呢?

Q3. 若是仍想保持這樣的結構,那sizeof的部份該如何改寫呢?

期待前輩們解惑!謝謝!


編輯記錄
vincechang 重新編輯於 2010-06-23 00:32:28, 註解 無‧
vincechang 重新編輯於 2010-06-23 00:33:50, 註解 無‧
vincechang 重新編輯於 2010-06-23 00:35:38, 註解 無‧
vincechang 重新編輯於 2010-06-23 00:38:17, 註解 無‧
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-06-23 10:04:42 IP:59.120.xxx.xxx 訂閱
A1. 沒有一個好的機制可以保證宣告後,不會重新調整,所以動態陣列,是無法 sizeof 的,你必須自己記錄 (所以叫動態陣列)
A2. 因為,已經知道大小(你自己指定的),且永遠不會變,規則就是不允許你變,不然 compiler 會過不了 (所以叫固定陣列)
A3. 比較簡單的方式
  1. typedef struct
  2. {
  3. BYTE p[2];
  4. BYTE *q;
  5. int size_of_q;
  6. } _STRUCT1;
當然還有其他技巧,可參考的很多,例如:C程式設計500個應用範例技巧大全集

xxx *q ---> *q
xxx q[] ---> q[0]
是同一件事 http://caterpillar.onlyfun.net/Gossip/CppGossip/PointerAndArray.html
===================引 用 vincechang 文 章===================
以下內容皆在同一個file中
[code cpp]
typedef unsigned char BYTE;
typedef struct
{
BYTE p[2];
BYTE q[];
} _STRUCT1;

_STRUCT1 gObj ={{1,2},{3,4}};//declaration and definition

BYTE r[]={5,6};//declaration and definition

void Function1(void)
{
BYTE m;
m = sizeof(gObj.p);//ok 沒問題
m = sizeof(gObj.q);//compile err = invalid application of 'sizeof' to incomplete type 'BYTE[]'
m = gObj.q[0];//ok 沒問題
m = gObj.q[1];//ok 沒問題
m = sizeof(r);//ok 沒問題
m = r[0];//ok 沒問題
m = r[1];//ok 沒問題
}
[/code]

實驗可知gObj.q[0],gObj.q[1]可以正確讀出,
表示這樣的結構中的陣列的宣告與
定義(初始化)沒有問題
但是這樣的寫法會產生compile err(第16行),
所以有一些疑問想要請教:

Q1. compile err的部份:我雖然在結構的宣告中並沒有指明q的長度,但是緊接著就進行結構變數gObj的定義,compiler難道看不出它已經是一個"complete type"的宣告了嗎?

Q2. 為什麼單一陣列用相同的方式進行宣告,sizeof卻沒有問題呢?

Q3. 若是仍想保持這樣的結構,那sizeof的部份該如何改寫呢?

期待前輩們解惑!謝謝!


vincechang
一般會員


發表:2
回覆:1
積分:0
註冊:2010-06-22

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-06-26 14:54:01 IP:118.160.xxx.xxx 訂閱
多謝指教!


===================引 用 syntax 文 章===================
A1. 沒有一個好的機制可以保證宣告後,不會重新調整,所以動態陣列,是無法 sizeof 的,你必須自己記錄 (所以叫動態陣列)
A2. 因為,已經知道大小(你自己指定的),且永遠不會變,規則就是不允許你變,不然 compiler 會過不了 (所以叫固定陣列)
A3. 比較簡單的方式
  1. typedefstruct
  2. {
  3. BYTEp[2];
  4. BYTE *q;
  5. int size_of_q;
  6. }_STRUCT1;
當然還有其他技巧,可參考的很多,例如:C程式設計500個應用範例技巧大全集


系統時間:2017-10-24 1:08:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!