উত্তর:
ইউনিয়নগুলি প্রায়শই পূর্ণসংখ্যা এবং ভাসমানগুলির বাইনারি উপস্থাপনার মধ্যে রূপান্তর করতে ব্যবহৃত হয়:
union
{
int i;
float f;
} u;
// Convert floating-point bits to integer:
u.f = 3.14159f;
printf("As integer: %08x\n", u.i);
যদিও এটি সি স্ট্যান্ডার্ড অনুযায়ী প্রযুক্তিগতভাবে অপরিজ্ঞাত আচরণ (আপনি কেবলমাত্র ক্ষেত্রটি পড়ার কথা যা সম্প্রতি লেখা হয়েছিল), এটি কার্যত যে কোনও সংকলকটিতে একটি সংজ্ঞায়িত পদ্ধতিতে কাজ করবে।
ইউনিয়নগুলি মাঝে মাঝে সি-তে সিউডো-পলিমারফিজম প্রয়োগ করতেও ব্যবহৃত হয়, কোনও কাঠামোর মধ্যে কিছু ট্যাগ দিয়ে বোঝায় যে এটিতে কী ধরণের অবজেক্ট রয়েছে এবং তারপরে সম্ভাব্য প্রকারগুলি একত্রিত করে:
enum Type { INTS, FLOATS, DOUBLE };
struct S
{
Type s_type;
union
{
int s_ints[2];
float s_floats[2];
double s_double;
};
};
void do_something(struct S *s)
{
switch(s->s_type)
{
case INTS: // do something with s->s_ints
break;
case FLOATS: // do something with s->s_floats
break;
case DOUBLE: // do something with s->s_double
break;
}
}
এটি struct S
28 এর পরিবর্তে আকারটি 12 বাইট হতে দেয় ।
ইউনিয়নগুলি এমবেডড প্রোগ্রামিং বা বিশেষত হার্ডওয়্যার / মেমোরিতে সরাসরি অ্যাক্সেস প্রয়োজন এমন পরিস্থিতিতে দরকারী। এখানে একটি তুচ্ছ উদাহরণ:
typedef union
{
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int dword;
} HW_Register;
HW_Register reg;
তারপরে আপনি নীচে নিবন্ধটি অ্যাক্সেস করতে পারেন:
reg.dword = 0x12345678;
reg.bytes.byte3 = 4;
এন্ডিয়ানাનેસ (বাইট অর্ডার) এবং প্রসেসরের আর্কিটেকচার অবশ্যই গুরুত্বপূর্ণ।
আর একটি দরকারী বৈশিষ্ট্য হ'ল বিট সংশোধক:
typedef union
{
struct {
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char reserved:4;
} bits;
unsigned char byte;
} HW_RegisterB;
HW_RegisterB reg;
এই কোডের সাহায্যে আপনি রেজিস্টার / মেমরি ঠিকানায় সরাসরি একক বিট অ্যাক্সেস করতে পারেন:
x = reg.bits.b2;
নিম্ন স্তরের সিস্টেম প্রোগ্রামিং একটি যুক্তিসঙ্গত উদাহরণ।
আইআইআরসি, আমি উপাদানগুলি বিটগুলিতে ব্রেকডাউন হার্ডওয়্যার রেজিস্টার করতে ইউনিয়নগুলি ব্যবহার করেছি। সুতরাং, আপনি একটি 8-বিট রেজিস্টার অ্যাক্সেস করতে পারেন (যেমনটি ছিল, সেদিন আমি উপাদানটি বিটগুলিতে করেছি ;-)
(আমি সঠিক বাক্য গঠনটি ভুলেছি তবে ...) এই কাঠামোটি একটি নিয়ন্ত্রণ রেজিস্টারকে নিয়ন্ত্রণ_বাইট হিসাবে বা পৃথক বিটের মাধ্যমে অ্যাক্সেস করার অনুমতি দেয়। প্রদত্ত অন্তর্নিহিততার জন্য সঠিক রেজিস্টার বিটগুলিতে বিটস মানচিত্রটি নিশ্চিত করা গুরুত্বপূর্ণ হবে।
typedef union {
unsigned char control_byte;
struct {
unsigned int nibble : 4;
unsigned int nmi : 1;
unsigned int enabled : 1;
unsigned int fired : 1;
unsigned int control : 1;
};
} ControlRegister;
বস্তুমুখী উত্তরাধিকারের প্রতিস্থাপন হিসাবে আমি এটি বেশ কয়েকটি গ্রন্থাগারে দেখেছি।
যেমন
Connection
/ | \
Network USB VirtualConnection
আপনি যদি সংযোগ "শ্রেণি" উপরের যেকোন একটি হতে চান তবে আপনি এমন কিছু লিখতে পারেন:
struct Connection
{
int type;
union
{
struct Network network;
struct USB usb;
struct Virtual virtual;
}
};
লাইবিনফিনিটিতে ব্যবহারের উদাহরণ: http://git.0x539.de/?p=infinote.git ;a=blob ;f=libinfinity/common/inf-session.c ;h=3e887f0d63bd754c6b5ec232948027cbbf4d61fc ;hb=HEAD#l74
ইউনিয়নগুলি ডেটা সদস্যদের যা পারস্পরিক একচেটিয়া একই মেমরিটি ভাগ করে নেওয়ার অনুমতি দেয়। এম্বেড থাকা সিস্টেমে যেমন মেমরির ঘাটতি হয় তখন এটি বেশ গুরুত্বপূর্ণ।
নিম্নলিখিত উদাহরণে:
union {
int a;
int b;
int c;
} myUnion;
এই ইউনিয়নটি 3 পৃথক int মানগুলির পরিবর্তে একক int এর স্থান গ্রহণ করবে। ব্যবহারকারী মান সেট করেন তাহলে একটি , এবং তারপর মান সেট খ , এটা মান ওভাররাইট করবে একটি যেহেতু তারা উভয় একই মেমরির অবস্থান ভাগ করছেন।
প্রচুর ব্যবহার শুধু grep union /usr/include/*
বা অনুরূপ ডিরেক্টরিতে। বেশিরভাগ union
কেসটি ক struct
এবং একটি সদস্যের মধ্যে আবৃত থাকে যাতে ইউনিয়নে কোন উপাদানটি অ্যাক্সেস করতে হয় তা জানায়। উদাহরণস্বরূপ man elf
বাস্তব জীবনের বাস্তবায়নের জন্য চেকআউট ।
এটিই মূল নীতি:
struct _mydata {
int which_one;
union _data {
int a;
float b;
char c;
} foo;
} bar;
switch (bar.which_one)
{
case INTEGER : /* access bar.foo.a;*/ break;
case FLOATING : /* access bar.foo.b;*/ break;
case CHARACTER: /* access bar.foo.c;*/ break;
}
এখানে আমার নিজস্ব কোডবেস থেকে একটি ইউনিয়নের উদাহরণ রয়েছে (মেমরি থেকে এবং প্যারাফ্রেস করা তাই এটি সঠিক নাও হতে পারে)। এটি আমি তৈরি করা দোভাষীগুলিতে ভাষার উপাদানগুলি সঞ্চয় করতে ব্যবহৃত হয়েছিল। উদাহরণস্বরূপ, নিম্নলিখিত কোড:
set a to b times 7.
নিম্নলিখিত ভাষার উপাদানগুলি নিয়ে গঠিত:
ভাষার উপাদানগুলি ' #define
' এর মান হিসাবে এইভাবে সংজ্ঞায়িত হয়েছিল :
#define ELEM_SYM_SET 0
#define ELEM_SYM_TO 1
#define ELEM_SYM_TIMES 2
#define ELEM_SYM_FULLSTOP 3
#define ELEM_VARIABLE 100
#define ELEM_CONSTANT 101
এবং প্রতিটি উপাদান সংরক্ষণের জন্য নিম্নলিখিত কাঠামোটি ব্যবহার করা হয়েছিল:
typedef struct {
int typ;
union {
char *str;
int val;
}
} tElem;
তারপরে প্রতিটি উপাদানের আকার ছিল সর্বোচ্চ ইউনিয়নের আকার (প্রকারের জন্য 4 বাইট এবং ইউনিয়নের জন্য 4 বাইট, যদিও সেগুলি আদর্শ মানের, প্রকৃত বাস্তবায়নের উপর নির্ভর করে আকার)।
একটি "সেট" উপাদান তৈরি করতে, আপনি ব্যবহার করবেন:
tElem e;
e.typ = ELEM_SYM_SET;
একটি "ভেরিয়েবল [বি]" উপাদান তৈরি করতে, আপনি এই ব্যবহার করবেন:
tElem e;
e.typ = ELEM_VARIABLE;
e.str = strdup ("b"); // make sure you free this later
একটি "ধ্রুবক [7]" উপাদান তৈরি করতে, আপনি এটি ব্যবহার করবেন:
tElem e;
e.typ = ELEM_CONSTANT;
e.val = 7;
এবং আপনি সহজেই এটি প্রসারিত করতে পারেন ( float flt
) বা যুক্তি ( struct ratnl {int num; int denom;}
) এবং অন্যান্য ধরণের অন্তর্ভুক্ত করতে।
মৌলিক প্রতিজ্ঞা যে str
এবং val
না মেমরি সংলগ্ন, তারা আসলে ওভারল্যাপ, তাই এটি যেখানে গঠন মেমরির অবস্থানে ভিত্তি করে মেমরি একই ব্লকে একটি ভিন্ন দৃশ্য পেয়ে, এখানে দেখানো হয়েছে, একটি উপায় আছে 0x1010
এবং পূর্ণসংখ্যার এবং পয়েন্টার উভয় 4 বাইট:
+-----------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-----+-----+
0x1014 | | |
0x1015 | str | val |
0x1016 | | |
0x1017 | | |
+-----+-----+
এটি যদি কেবল কোনও কাঠামোর মধ্যে থাকে তবে এটি দেখতে এটির মতো হবে:
+-------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-------+
0x1014 | |
0x1015 | str |
0x1016 | |
0x1017 | |
+-------+
0x1018 | |
0x1019 | val |
0x101A | |
0x101B | |
+-------+
make sure you free this later
মন্তব্য ধ্রুবক উপাদান থেকে সরানো হতে?
আমি বলতে চাই মেমরির পুনঃব্যবহার করা আরও সহজ করে তোলে যা বিভিন্ন উপায়ে ব্যবহার করা যেতে পারে, যেমন মেমরি সঞ্চয় করে। যেমন আপনি কিছু "বৈকল্পিক" কাঠামো করতে চান যা একটি সংক্ষিপ্ত স্ট্রিং পাশাপাশি একটি সংখ্যা সংরক্ষণ করতে সক্ষম:
struct variant {
int type;
double number;
char *string;
};
একটি 32 বিট সিস্টেমে এটির প্রতিটি উদাহরণের জন্য কমপক্ষে 96 বিট বা 12 বাইট ব্যবহার করা হবে variant
।
ইউনিয়ন ব্যবহার করে আপনি আকারটি 64 বিট বা 8 বাইটে হ্রাস করতে পারবেন:
struct variant {
int type;
union {
double number;
char *string;
} value;
};
আপনি আরও বিভিন্ন পরিবর্তনশীল প্রকার ইত্যাদি যুক্ত করতে চাইলে আপনি আরও বেশি সঞ্চয় করতে সক্ষম হবেন এটি সত্য হতে পারে, আপনি শূন্য পয়েন্টার castালাইয়ের অনুরূপ জিনিসগুলি করতে পারেন - তবে ইউনিয়ন এটিকে অনেক বেশি অ্যাক্সেসযোগ্য পাশাপাশি টাইপ করার মতো করে তোলে নিরাপদ। এই ধরনের সঞ্চয়গুলি বিশাল শোনাচ্ছে না তবে আপনি এই স্ট্রাক্টের সমস্ত দৃষ্টান্তের জন্য ব্যবহৃত মেমরির এক তৃতীয়াংশ সংরক্ষণ করছেন।
আপনার যখন এই ধরণের নমনীয় কাঠামোর প্রয়োজন হয় তখন একটি নির্দিষ্ট অনুষ্ঠানের কথা ভাবা কঠিন, সম্ভবত কোনও বার্তা প্রোটোকলে যেখানে আপনি বিভিন্ন আকারের বার্তা প্রেরণ করবেন, তবে তারপরে সম্ভবত আরও ভাল এবং আরও বেশি প্রোগ্রামার বান্ধব বিকল্প রয়েছে।
ইউনিয়নগুলি অন্যান্য ভাষায় বৈকল্পিক ধরণের মতো - তারা একবারে কেবল একটি জিনিস ধরে রাখতে পারে তবে আপনি কীভাবে এটি ঘোষণা করেন তার উপর নির্ভর করে সেই জিনিসটি কোনও ইনট, ফ্লোট ইত্যাদি হতে পারে।
উদাহরণ স্বরূপ:
typedef union MyUnion MYUNION;
union MyUnion
{
int MyInt;
float MyFloat;
};
আপনি সর্বশেষে সেট করেছেন তার উপর নির্ভর করে মাইইউনিয়নে কেবলমাত্র কোনও ইন্ট বা একটি ফ্লোট থাকবে । সুতরাং এটি করছেন:
MYUNION u;
u.MyInt = 10;
আপনার এখন 10 এর সমান ইন্টি;
u.MyFloat = 1.0;
আপনি এখন 1.0 এর সমান ফ্লোট ধারণ করে holds এটি আর কোন int রাখে না। স্পষ্টত এখন আপনি যদি প্রিন্টফ চেষ্টা করেন এবং করেন ("MyInt =% d", u.MyInt); তবে আপনি সম্ভবত একটি ত্রুটি পেতে চলেছেন, যদিও আমি নির্দিষ্ট আচরণ সম্পর্কে নিশ্চিত নই of
ইউনিয়নের আকার তার বৃহত্তম ক্ষেত্রের আকার দ্বারা নির্ধারিত হয়, এক্ষেত্রে ভাসা।
sizeof(int) == sizeof(float)
( == 32
) সাধারণত
এই উত্তরগুলির মধ্যে অনেকগুলি এক ধরণের থেকে অন্য প্রকারে কাস্টিংয়ের কাজ করে। আমি ইউনিয়নগুলির মধ্যে একই ধরণের আরও কয়েকটি (যেমন কোনও সিরিয়াল ডেটা স্ট্রিম পার্স করার সময়) সহ সর্বাধিক ব্যবহার পাই। তারা ফ্রেমযুক্ত প্যাকেটের পার্সিং / নির্মাণকে তুচ্ছ হতে দেয়।
typedef union
{
UINT8 buffer[PACKET_SIZE]; // Where the packet size is large enough for
// the entire set of fields (including the payload)
struct
{
UINT8 size;
UINT8 cmd;
UINT8 payload[PAYLOAD_SIZE];
UINT8 crc;
} fields;
}PACKET_T;
// This should be called every time a new byte of data is ready
// and point to the packet's buffer:
// packet_builder(packet.buffer, new_data);
void packet_builder(UINT8* buffer, UINT8 data)
{
static UINT8 received_bytes = 0;
// All range checking etc removed for brevity
buffer[received_bytes] = data;
received_bytes++;
// Using the struc only way adds lots of logic that relates "byte 0" to size
// "byte 1" to cmd, etc...
}
void packet_handler(PACKET_T* packet)
{
// Process the fields in a readable manner
if(packet->fields.size > TOO_BIG)
{
// handle error...
}
if(packet->fields.cmd == CMD_X)
{
// do stuff..
}
}
সম্পাদনা করুন endianness এবং struct প্যাডিং সম্পর্কে মন্তব্য, বৈধ, এবং মহান উদ্বেগ। আমি এম্বেডড সফ্টওয়্যারগুলিতে কোডের এই বডিটি প্রায় সম্পূর্ণ ব্যবহার করেছি, যার বেশিরভাগ অংশে আমার পাইপের উভয় প্রান্তের নিয়ন্ত্রণ ছিল।
ইউনিয়নগুলি দুর্দান্ত। ইউনিয়নগুলির একটি চতুর ব্যবহার আমি দেখেছি কোনও ইভেন্টের সংজ্ঞা দেওয়ার সময় সেগুলি ব্যবহার করা। উদাহরণস্বরূপ, আপনি সিদ্ধান্ত নিতে পারেন যে কোনও ইভেন্ট 32 বিট।
এখন, 32 টি বিটের মধ্যে, আপনি ইভেন্টের প্রেরকের সনাক্তকারী হিসাবে প্রথম 8 টি বিট নির্দিষ্ট করতে পছন্দ করতে পারেন ... কখনও কখনও আপনি ইভেন্টটিকে পুরোপুরি ডিল করেন, কখনও কখনও আপনি এটি বিছিন্ন করেন এবং এর উপাদানগুলি তুলনা করেন। ইউনিয়নগুলি আপনাকে উভয় ক্ষেত্রেই নমনীয়তা দেয়।
ইউনিয়ন ইভেন্ট { স্বাক্ষরবিহীন দীর্ঘ ইভেন্টকোড; স্বাক্ষরযুক্ত চর ইভেন্ট ইভেন্টস [4]; };
VARIANT
সিওএম ইন্টারফেসে এর ব্যবহার কী ? এর দুটি ক্ষেত্র রয়েছে - "টাইপ" এবং একটি ইউনিয়ন একটি আসল মান ধারণ করে যা "টাইপ" ক্ষেত্রের উপর নির্ভর করে চিকিত্সা করা হয়।
আমি এম্বেড থাকা ডিভাইসগুলির জন্য কোডিং করার সময় ইউনিয়ন ব্যবহার করেছি। আমার সি ইনট রয়েছে যা 16 বিট দীর্ঘ। এবং যখন আমাকে EEPROM থেকে / স্টোর থেকে পড়তে হবে তখন আমাকে উচ্চতর 8 টি বিট এবং নিম্ন 8 বিটগুলি উদ্ধার করতে হবে। সুতরাং আমি এইভাবে ব্যবহার করেছি:
union data {
int data;
struct {
unsigned char higher;
unsigned char lower;
} parts;
};
কোডটি পড়া সহজ হয় তাই এটি স্থানান্তরিত হয় না।
অন্যদিকে, আমি কিছু পুরানো সি ++ এসএলএল কোড দেখেছি যা স্টাইল বরাদ্দকারীর জন্য ইউনিয়ন ব্যবহার করে। আপনি যদি আগ্রহী হন তবে স্যাজি স্টাইল উত্স কোডটি পড়তে পারেন । এখানে এটির একটি অংশ:
union _Obj {
union _Obj* _M_free_list_link;
char _M_client_data[1]; /* The client sees this. */
};
struct
আপনার higher
/ আপনার চারপাশে একটি গ্রুপিংয়ের প্রয়োজন হবে না lower
? এই মুহুর্তে উভয়েরই কেবল প্রথম বাইটের দিকে নির্দেশ করা উচিত।
এটি একবার দেখুন: X.25 বাফার কমান্ড হ্যান্ডলিং
অনেকগুলি সম্ভাব্য এক্স.25 কমান্ডগুলির মধ্যে একটি একটি বাফারে প্রাপ্ত হয় এবং সমস্ত সম্ভাব্য কাঠামোর একটি ইউনিয়ন ব্যবহার করে স্থানে পরিচালনা করা হয়।
সি এর প্রাথমিক সংস্করণগুলিতে, সমস্ত কাঠামো ঘোষণাগুলি ক্ষেত্রগুলির একটি সাধারণ সেট ভাগ করবে। প্রদত্ত:
struct x {int x_mode; int q; float x_f};
struct y {int y_mode; int q; int y_l};
struct z {int z_mode; char name[20];};
একটি সংকলক মূলত কাঠামোর আকারের (এবং সম্ভবত সারিবদ্ধকরণ) একটি টেবিল এবং কাঠামোর সদস্যদের নাম, প্রকার এবং অফসেটের একটি পৃথক টেবিল তৈরি করতে পারে। সংকলকটি কোন কাঠামোর সাথে সম্পর্কিত ছিল তা ট্র্যাক করেনি, এবং টাইপ এবং অফসেটটি মিলে গেলে (সদস্য q
হিসাবে struct x
এবং এর সাথে struct y
) দুটি কাঠামোগত একই নামের সদস্য থাকতে দেয় । P যদি কোনও কাঠামোর ধরণের পয়েন্টার হয়, p-> q পয়েন্টার পিতে "q" এর অফসেট যুক্ত করবে এবং ফলাফলের ঠিকানা থেকে "ইনট" আনবে।
উপরোক্ত শব্দার্থবিজ্ঞানের ভিত্তিতে এমন একটি ফাংশন লেখা সম্ভব হয়েছিল যা একাধিক ধরণের কাঠামোর বিনিময়ে কিছু কার্যকর ক্রিয়াকলাপ সম্পাদন করতে পারে, তবে শর্ত থাকে যে ফাংশনটির দ্বারা ব্যবহৃত সমস্ত ক্ষেত্রগুলি কাঠামোর মধ্যে দরকারী ক্ষেত্রগুলির সাথে রেখাযুক্ত রয়েছে। এটি একটি দরকারী বৈশিষ্ট্য ছিল, এবং প্রশ্নে কাঠামোর ধরণের বিরুদ্ধে কাঠামো অ্যাক্সেসের জন্য ব্যবহৃত সদস্যদের বৈধতা দেওয়ার জন্য সি পরিবর্তন করার অর্থ একই ঠিকানায় একাধিক নামযুক্ত ক্ষেত্র থাকতে পারে এমন কাঠামো থাকার উপায়ের অভাবে এটি হারাতে হবে। সি তে "ইউনিয়ন" প্রকার যুক্ত করা সেই ফাঁকটি কিছুটা পূরণ করতে সহায়তা করেছিল (যদিও তা নয়, আইএমএইচওও, পাশাপাশি এটি হওয়া উচিত ছিল)।
ইউনিয়নগুলির এই শূন্যস্থান পূরণের ক্ষমতার একটি অপরিহার্য অংশটি হ'ল ইউনিয়ন সদস্যের পয়েন্টারটিকে সেই সদস্য সমন্বিত যে কোনও ইউনিয়নে পয়েন্টারে রূপান্তর করা যায় এবং যে কোনও ইউনিয়নে একটি পয়েন্টারকে কোনও সদস্যকে পয়েন্টারে রূপান্তর করা যেতে পারে। C89 স্ট্যান্ডার্ড স্পষ্টভাবে বলতে না পারলেও একটি ভোটদান T*
একটি সরাসরি U*
একটি পয়েন্টার তা কোন ইউনিয়ন টাইপ কাস্ট উভয় ধারণকারী সমতূল্য ছিল T
এবং U
, এবং তারপর ভোটদান যে U*
, আধুনিক ঢালাই ক্রম কোন সংজ্ঞায়িত আচরণ দ্বারা প্রভাবিত হতে হবে ইউনিয়ন টাইপ ব্যবহৃত, এবং স্ট্যান্ডার্ড থেকে একটি সরাসরি ঢালাই জন্য কোন বিপরীত শব্দার্থবিদ্যা উল্লেখ করা হয়নি T
করতে U
। তদ্ব্যতীত, যেখানে কোনও ফাংশন অজানা উত্সের পয়েন্টার পেয়েছে, কোনও রূপটি T*
রূপান্তর করে এর মাধ্যমে কোনও অবজেক্ট লেখার আচরণT*
একটি থেকেU*
, এবং তারপরে অবজেক্টটি পড়া U*
টাইপের সদস্যের মাধ্যমে ইউনিয়ন লেখার T
এবং টাইপ হিসাবে পড়া সমতুল্য U
, যা কয়েকটি ক্ষেত্রে স্ট্যান্ডার্ড-সংজ্ঞায়িত হবে (উদাহরণস্বরূপ সাধারণ প্রাথমিক অনুক্রমের সদস্যদের অ্যাক্সেস করার সময়) এবং বাস্তবায়ন-সংজ্ঞায়িত (পরিবর্তে অপরিজ্ঞাত ) বাকি জন্য। প্রোগ্রামগুলির পক্ষে ইউনিয়নের ধরণের প্রকৃত বস্তুগুলির সাথে সিআইএস গ্যারান্টিগুলি অপব্যবহার করা বিরল ছিল, তবে অজানা উত্সের বস্তুগুলিকে পয়েন্টারগুলির মতো ইউনিয়ন সদস্যদের সাথে পয়েন্টারের মতো আচরণ করতে হয়েছিল এবং এর সাথে সম্পর্কিত আচরণগত গ্যারান্টি থাকতে হবে তা কাজে লাগানো আরও সাধারণ বিষয় ছিল।
foo
যদি int
অফসেট 8 সহ একটি হয় তবে anyPointer->foo = 1234;
তার অর্থ "কোনও পয়েন্টারে ঠিকানা নিন, এটি 8 বাইট দ্বারা স্থানচ্যুত করুন এবং ফলাফলের ঠিকানায় 1234 মানের একটি পূর্ণসংখ্যা স্টোর সম্পাদন করুন The সংকলকটি anyPointer
সনাক্ত বা সনাক্তকরণের প্রয়োজন হবে না যে কোনও কাঠামোর ধরণ যা foo
এর সদস্যদের মধ্যে তালিকাভুক্ত করেছিল
anyPointer
স্ট্রাক্ট সদস্যের সাথে পরিচয় দেয় কিনা তা যদি জানেন না , তবে সংকলক to have a member with the same name only if the type and offset matched
আপনার পোস্টের এই শর্তটি কীভাবে পরীক্ষা করবে ?
p->foo
নির্ভর করে টাইপ এবং অফসেটের উপর foo
। মূলত, p->foo
ছিল সংক্ষিপ্ত *(typeOfFoo*)((unsigned char*)p + offsetOfFoo)
। আপনার পরবর্তী প্রশ্ন হিসাবে, যখন কোনও সংকলক স্ট্রাক্ট সদস্য সংজ্ঞাটির মুখোমুখি হয়, তখন প্রয়োজন হয় যে সেই নামটি সহ কোনও সদস্যই উপস্থিত নেই, বা সেই নামের সদস্যটির একই ধরণ এবং অফসেট রয়েছে; আমি অনুমান করব যে কোনও মেলে না এমন স্ট্রাক্ট সদস্য সংজ্ঞা থাকলে অস্তিত্ব নষ্ট হয়ে গেছে, তবে কীভাবে এটি ত্রুটিগুলি পরিচালনা করেছিল তা আমি জানি না।
একটি সহজ এবং খুব দরকারী উদাহরণ, ....
কল্পনা করুন:
আপনার কাছে uint32_t array[2]
রয়েছে এবং বাইট চেইনের তৃতীয় এবং চতুর্থ বাইট অ্যাক্সেস করতে চান। আপনি করতে পারে *((uint16_t*) &array[1])
। তবে দুঃখের সাথে এই কঠোর এলিয়াসিং বিধি ভঙ্গ করে!
তবে পরিচিত সংকলকগুলি আপনাকে নিম্নলিখিতটি করতে অনুমতি দেয়:
union un
{
uint16_t array16[4];
uint32_t array32[2];
}
প্রযুক্তিগতভাবে এটি এখনও নিয়ম লঙ্ঘন। তবে সমস্ত জ্ঞাত মান এই ব্যবহারকে সমর্থন করে।