2012-03-15 8 views
6

मैं जानना चाहता हूं कि मैं एक रिकॉर्ड कैसे घोषित करूं, जिसमें कुछ निश्चित मूल्य हैं। मुझे इस पैटर्न का उपयोग कर डेटा भेजने की जरूरत है: Byte($FF)-Byte(0..250)-Byte(0..250)। मैं इसके लिए record का उपयोग कर रहा हूं और मैं इसका पहला मान निरंतर रखना चाहता हूं, ताकि इसे गड़बड़ न किया जा सके। जैसे:रिकॉर्ड में एक निश्चित मूल्य कैसे घोषित करें?

TPacket = record 
    InitByte: byte; // =255, constant 
    FirstVal, 
    SecondVal: byte; 
end; 
+3

आप प्रकार – OnTheFly

+0

subrange को यदि सब आप कर रहे हैं एक TPacket में बाइट मूल्यों है सहारा सकता है शामिल करने के लिए, मैं बजाय RawByteString का प्रयोग करेंगे और सिर्फ नामित स्थिरांक को परिभाषित InitByte = 0, FIrstVal = 1, और इसी तरह। एएनडी मैं यह सुनिश्चित करता हूं कि शुरुआती मूल्य मेरे पैकेटबिल्ड फ़ंक्शन में कोड में कर कर सही निरंतर मूल्य था। –

+1

आप किस डेल्फी संस्करण का उपयोग करेंगे? – kobik

उत्तर

12

आप एक निर्माता पर भरोसा नहीं कर सकते, क्योंकि कक्षा के विपरीत, रिकॉर्ड्स उन्हें इस्तेमाल करने की आवश्यकता नहीं है, डिफ़ॉल्ट parameterless निर्माता परोक्ष इस्तेमाल किया जा रहा।

लेकिन आप एक निरंतर क्षेत्र का उपयोग कर सकते हैं:

type 
    TPacket = record 
    type 
    TBytish = 0..250; 
    const 
    InitByte : Byte = 255; 
    var 
    FirstVal, 
    SecondVal: TBytish; 
    end; 

फिर इस एक नियमित रूप से रिकॉर्ड के रूप में, को छोड़कर आप की जरूरत नहीं है कि (और आप नहीं कर सकते हैं) का उपयोग InitByte फ़ील्ड बदलें।
FillChar निरंतर क्षेत्र को संरक्षित करता है और अपेक्षित व्यवहार करता है।

procedure TForm2.FormCreate(Sender: TObject); 
var 
    r: TPacket; 
begin 
    FillChar(r, SizeOf(r), #0); 
    ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal])); 
    // r.InitByte := 42; // not allowed by compiler 
    // r.FirstVal := 251; // not allowed by compiler 
    r.FirstVal := 1; 
    r.SecondVal := 2; 
    ShowMessage(Format('InitByte = %d, FirstVal = %d, SecondVal = %d', [r.InitByte, r.FirstVal,r.SecondVal])); 
end; 

अपडेट किया गया नेस्टेड प्रकार रेंज 0..250

+1

बहुत बढ़िया। पहला असली जवाब। –

+0

@ माइक, लगभग है। François, आप 'FirstVal' और 'SecondVal' रखने के लिए सीमा याद कर रहे हैं। अगर मुझे यह सही लगता है, तो उन्हें '0..250' की सीमा में होना चाहिए। लेकिन फिर आप 'फिलर' के साथ समस्या को पूरा कर सकते हैं जो इस सीमाओं से मूल्य निर्धारित कर सकता है (निश्चित रूप से रेंज की जांच के साथ)। – TLama

+1

@TLama, मैं ओपी की रिकॉर्ड घोषणा पर भरोसा कर रहा था और सीमा की बात याद कर चुका था। उप-प्रकार के साथ अद्यतन उत्तर ... –

2

डेल्फी के आधुनिक संस्करण रिकॉर्ड विधियों की अनुमति देते हैं। आप क्षेत्र में बदलाव करने से किसी को नहीं रोका जा सकता है आप कम से कम यह उचित रूप से प्रारंभ कर सकते हैं:

type 
    TPacket = record 
    InitByte: byte; // =255, constant 
    FirstVal, 
    SecondVal: byte; 
    constructor Create(val1, val2 : byte); 
    end; 


constructor TPacket.Create(val1, val2: byte); 
begin 
    InitByte := 255; 
    FirstVal := val1; 
    SecondVal := val2; 
end; 
+1

दुर्भाग्य से, आप कन्स्ट्रक्टर के उपयोग को लागू नहीं कर सकते ... –

0

को देखते हुए इस तथ्य रिकॉर्ड अब गुण हो सकता है, आप के रूप में एक रिकॉर्ड को परिभाषित कर सकते हैं:

TMixedFixed = record 
strict private 
    FFixed: byte; 
    FVariable1: byte; 
    FVariable2: byte; 
public 
    property Fixed read FFixed; 
    property Variable read FVariable write FVariable; 
    constructor Create(Var1, Var2: byte); 
end; 

constructor TMixedFixed.create(Var1, Var2: byte); 
begin 
    FFixed:= 255; 
    FVariable1:= Var1; 
    FVariable2:= Var2; 
end; 

इस तथ्य को देखते हुए कि वास्तविक चर सख्त निजी हैं, आपको विशेष जादू के बिना उन्हें छूने में सक्षम नहीं होना चाहिए। हालांकि आपको 'निश्चित' मानों को init करने के लिए कन्स्ट्रक्टर का उपयोग करना होगा।

+0

यह एक चर घोषित करने से रोकता है और इसका उपयोग किए बिना मानक रिकॉर्ड के रूप में उपयोग नहीं करता है कन्स्ट्रक्टर आपके पास सिर्फ 'FFixed' में कचरा होगा और इसे बदलने का कोई तरीका नहीं है ... –

+0

@ फ्रैंकोइस, क्या आप डिफ़ॉल्ट कन्स्ट्रक्टर को ओवरराल नहीं कर सकते? – Johan

+0

मुझे नहीं पता कि। डिफ़ॉल्ट कन्स्ट्रक्टर इतना प्रमुख है कि यह आपको एक और पैरामीटर रहित कन्स्ट्रक्टर घोषित करने से भी रोकता है। आपके द्वारा प्रदान किए जाने वाले किसी भी कस्टम कंस्ट्रक्टर में पैरामीटर होना आवश्यक है। [Docwiki] देखें (http://docwiki.embarcadero.com/RADStudio/en/Structured_Types): "रिकॉर्ड्स स्वचालित रूप से डिफॉल्ट नो-तर्क कन्स्ट्रक्टर का उपयोग करके बनाए जाते हैं, लेकिन कक्षाओं को स्पष्ट रूप से बनाया जाना चाहिए। क्योंकि रिकॉर्ड्स में डिफ़ॉल्ट नो- तर्क कन्स्ट्रक्टर, किसी भी उपयोगकर्ता द्वारा परिभाषित रिकॉर्ड कन्स्ट्रक्टर में एक या अधिक पैरामीटर होना चाहिए। " –

0

यह सबसे आसान तरीका है:

type 
    TPacket = record 
    InitByte: byte; // =255, constant 
    FirstVal, 
    SecondVal: byte; 
    end; 

var 
    Packet : TPacket = (InitByte: 255); 

const 
    Packet1 : TPacket = (InitByte: 255); 
+1

नहीं, यह एकमात्र तरीका नहीं है, मेरा जवाब देखें।और, बीटीडब्ल्यू, आप अपने पैकेट वैरिएबल (कंपाइलर त्रुटि E2195) जैसे स्थानीय चर प्रारंभ नहीं कर सकते हैं। –

संबंधित मुद्दे