আমি নীচের মত কাঠামো সমন্বিত অনেক প্রোগ্রাম দেখেছি
typedef struct
{
int i;
char k;
} elem;
elem user;
কেন এত ঘন ঘন দরকার হয়? কোন নির্দিষ্ট কারণ বা প্রযোজ্য অঞ্চল?
struct * ptr
কারণ
আমি নীচের মত কাঠামো সমন্বিত অনেক প্রোগ্রাম দেখেছি
typedef struct
{
int i;
char k;
} elem;
elem user;
কেন এত ঘন ঘন দরকার হয়? কোন নির্দিষ্ট কারণ বা প্রযোজ্য অঞ্চল?
struct * ptr
কারণ
উত্তর:
গ্রেগ হিউগিল যেমন বলেছিলেন, টাইপিডেফের অর্থ আপনাকে আর struct
পুরো জায়গা জুড়ে লিখতে হবে না। এটি কেবল কীস্ট্রোকগুলি সংরক্ষণ করে না, এটি কোড ক্লিনারও তৈরি করতে পারে কারণ এটি একটি স্মিডজেনকে আরও বিমূর্ততা সরবরাহ করে।
স্টাফ পছন্দ
typedef struct {
int x, y;
} Point;
Point point_new(int x, int y)
{
Point a;
a.x = x;
a.y = y;
return a;
}
আপনার যখন পুরো জায়গা জুড়ে "স্ট্রাক্ট" কীওয়ার্ডটি দেখার প্রয়োজন হবে না তখন পরিষ্কার হয়ে যায়, আপনার ভাষাতে "পয়েন্ট" নামে একটি প্রকৃতপক্ষে সত্যই আছে বলে মনে হচ্ছে। কোনটি, এর পরে typedef
, আমি অনুমান করি।
এছাড়াও মনে রাখবেন যে আপনার উদাহরণটি (এবং আমার) struct
নিজেই নামকরণ বাদ দিলে, যখন আপনি একটি অস্বচ্ছ প্রকার সরবরাহ করতে চান তখন এটির নামকরণও কার্যকর। তারপরে আপনার শিরোনামে যেমন কোড থাকে, উদাহরণস্বরূপ:
typedef struct Point Point;
Point * point_new(int x, int y);
এবং তারপরে struct
বাস্তবায়ন ফাইলে সংজ্ঞাটি সরবরাহ করুন:
struct Point
{
int x, y;
};
Point * point_new(int x, int y)
{
Point *p;
if((p = malloc(sizeof *p)) != NULL)
{
p->x = x;
p->y = y;
}
return p;
}
এই পরবর্তী ক্ষেত্রে আপনি মান অনুসারে পয়েন্টটি ফিরিয়ে দিতে পারবেন না, কারণ এর সংজ্ঞাটি শিরোলেখ ফাইলটির ব্যবহারকারীদের থেকে গোপন রয়েছে। উদাহরণস্বরূপ, এটি জিটিকে + তে ব্যাপকভাবে ব্যবহৃত একটি কৌশল ।
আপডেট আপডেট নোট করুন যে এখানে খুব সম্মানিত সি প্রকল্প রয়েছে যেখানে typedef
লুকানোর struct
জন্য এই ব্যবহারটি একটি খারাপ ধারণা হিসাবে বিবেচিত হয়, লিনাক্স কার্নেল সম্ভবত এটি সবচেয়ে সুপরিচিত প্রকল্প। লিনাসের রাগান্বিত শব্দের জন্য লিনাক্স কার্নেল কোডিং স্টাইল নথির অধ্যায় 5 দেখুন । :) আমার বক্তব্যটি হ'ল এই প্রশ্নে "উচিত" সম্ভবত পাথরের উপরে সেট করা নেই।
কত লোক এই ভুল করে তা অবাক করে দেয়। অনুগ্রহ করে সি তে টাইপড স্ট্রাকগুলি ব্যবহার করবেন না, এটি অকারণে গ্লোবাল নেমস্পেসকে দূষিত করে যা সাধারণত বড় সি প্রোগ্রামগুলিতে ইতিমধ্যে খুব দূষিত।
এছাড়াও, ট্যাগ নাম ছাড়া টাইপফাইড স্ট্রাইকগুলি শিরোনাম ফাইলগুলির মধ্যে সম্পর্কের ক্রমকে অর্পণ করার অপ্রয়োজনীয় চাপিয়ে দেওয়ার একটি বড় কারণ।
বিবেচনা:
#ifndef FOO_H
#define FOO_H 1
#define FOO_DEF (0xDEADBABE)
struct bar; /* forward declaration, defined in bar.h*/
struct foo {
struct bar *bar;
};
#endif
এই জাতীয় সংজ্ঞা সহ, টাইপিডেফগুলি ব্যবহার না করে, একটি কমপিল্যান্ড ইউনিটের পক্ষে foo.h FOO_DEF
সংজ্ঞা দেওয়া সম্ভব। যদি এটি foo
স্ট্রাক্টের 'বার' সদস্যকে অবজ্ঞা করার চেষ্টা না করে তবে "বার। Hl" ফাইলটি অন্তর্ভুক্ত করার প্রয়োজন হবে না।
এছাড়াও, যেহেতু ট্যাগের নাম এবং সদস্যের নামগুলির মধ্যে নামের স্থানগুলি পৃথক, তাই খুব পঠনযোগ্য কোড যেমন এটি লেখা সম্ভব:
struct foo *foo;
printf("foo->bar = %p", foo->bar);
নাম স্পেসগুলি পৃথক হওয়ায়, তার কাঠামোর নামের সাথে ভেরিয়েবলের নামকরণে কোনও বিরোধ নেই।
যদি আমাকে আপনার কোড বজায় রাখতে হয় তবে আমি আপনার টাইপডেফ স্ট্রাক্টগুলি সরিয়ে দেব।
typedef struct X { ... } X
। আপনি সংক্ষিপ্ত ফর্মটি X
সংজ্ঞাটি যেখানেই সংজ্ঞাটি উপলভ্য পাওয়া যায় তা ব্যবহার করতে পারেন, তবে তবুও ফরোয়ার্ড-ডিক্লেয়ার এবং struct X
ইচ্ছামত ব্যবহার করতে পারেন ।
ড্যান সাকসের একটি পুরানো নিবন্ধ থেকে ( http://www.ddj.com/cpp/184403396?pgno=3 ):
নামকরণের স্ট্রিংগুলির জন্য সি ভাষার নিয়মগুলি একটু উদ্বেগজনক তবে সেগুলি বেশ নিরীহ। যাইহোক, যখন সি ++ ক্লাসে প্রসারিত করা হয়, তখন সেই একই নিয়মগুলি বাগগুলি ক্রল করার জন্য সামান্য ফাটল উন্মুক্ত করে।
সি তে, নামটি উপস্থিত হ'ল
struct s { ... };
একটি ট্যাগ। ট্যাগের নাম কোনও প্রকারের নাম নয়। উপরোক্ত সংজ্ঞা দেওয়া, ঘোষণা যেমন
s x; /* error in C */ s *p; /* error in C */
সি তে ত্রুটি রয়েছে আপনাকে এগুলি লিখতে হবে
struct s x; /* OK */ struct s *p; /* OK */
ইউনিয়ন এবং গণনাগুলির নামগুলিও প্রকারের পরিবর্তে ট্যাগ।
সি-তে, ট্যাগগুলি অন্যান্য সমস্ত নাম থেকে পৃথক (ফাংশন, প্রকার, ভেরিয়েবল এবং গণনার ধাপগুলির জন্য)। সি সংকলকগুলি প্রতীক টেবিলের মধ্যে ট্যাগগুলি বজায় রাখে যা ধারণাগতভাবে অন্য কোনও নাম ধারণ করে ছক থেকে শারীরিকভাবে পৃথক না হয়। সুতরাং, কোনও সি প্রোগ্রামের পক্ষে একই স্কোলে একই বানান সহ একটি ট্যাগ এবং অন্য নাম উভয়ই রাখা সম্ভব। উদাহরণ স্বরূপ,
struct s s;
এটি একটি বৈধ ঘোষণা যা প্রকারের স্ট্রাক্টের পরিবর্তনশীল গুলি ঘোষণা করে। এটি ভাল অনুশীলন নাও হতে পারে তবে সি সংকলকদের অবশ্যই এটি গ্রহণ করতে হবে। কেন সি এইভাবে ডিজাইন করা হয়েছিল তার যৌক্তিকতা আমি কখনই দেখিনি। আমি সবসময় ভেবেছিলাম এটি একটি ভুল ছিল, তবে এটি আছে।
অনেক প্রোগ্রামার (প্রকৃতপক্ষে আপনার সহ) স্ট্রাক্ট নামগুলি টাইপ নাম হিসাবে ভাবতে পছন্দ করে, তাই তারা টাইপডেফ ব্যবহার করে ট্যাগের জন্য একটি এলিফ নির্ধারণ করে। উদাহরণস্বরূপ, সংজ্ঞায়িত করা
struct s { ... }; typedef struct s S;
আপনাকে যেমন স্ট্রাক্ট এস এর জায়গায় এস ব্যবহার করতে দেয়
S x; S *p;
কোনও প্রোগ্রাম এস এবং প্রকার এবং একটি ভেরিয়েবল (বা ফাংশন বা গণনা ধ্রুবক) উভয়ের নাম হিসাবে ব্যবহার করতে পারে না:
S S; // error
এটা ভাল.
স্ট্রাক্ট, ইউনিয়ন বা এনাম সংজ্ঞাতে ট্যাগের নামটি isচ্ছিক। অনেক প্রোগ্রামার স্ট্রাইক সংজ্ঞাটি টাইপইফের মধ্যে ভাঁজ করে এবং ট্যাগ সহ পুরোপুরি সরবরাহ করে, যেমন:
typedef struct { ... } S;
লিঙ্কযুক্ত নিবন্ধে একটি প্রয়োজন নেই যে সি ++ আচরণ typedef
সূক্ষ্ম নাম গোপনে সমস্যা তৈরি করতে পারে তা নিয়েও আলোচনা রয়েছে । এই সমস্যাগুলি রোধ করতে, এটি typedef
আপনার ক্লাস এবং সি ++ এর স্ট্রাক্টগুলির পক্ষে খুব ভাল ধারণা , যদিও প্রথম নজরে এটি অপ্রয়োজনীয় বলে মনে হয়। সি ++ typedef
এ নামটি গোপন করার সাথে একটি ত্রুটি হয়ে যায় যা সংকলক আপনাকে সম্ভাব্য সমস্যার কোনও গোপন উত্সের পরিবর্তে বলে দেয়।
int stat(const char *restrict path, struct stat *restrict buf)
। stat
সাধারণ নাম জায়গাতে এবং struct stat
ট্যাগ নামের জায়গাতে আপনার একটি ফাংশন রয়েছে ।
একটি ব্যবহার typedef
এড়াতে লিখতে থাকার struct
প্রত্যেক সময় আপনি যে ধরনের একটি ভেরিয়েবল ডিক্লেয়ার:
struct elem
{
int i;
char k;
};
elem user; // compile error!
struct elem user; // this is correct
typedef
। আপনি করতে পারেন typedef struct foo foo;
। অবশ্যই struct
মূলশব্দটির আরও বেশি প্রয়োজন নেই যা দরকারী ইঙ্গিত হতে পারে যে টাইপ ওরফে আমরা যে কাঠামোটি দেখি তা কোনও কাঠামোর জন্য একটি নাম তবে এটি সাধারণত খারাপ নয়। একটি ক্ষেত্রে বিবেচনা যেখানে ফলে টাইপ ওরফে এর আইডেন্টিফায়ার typedef
ইঙ্গিত করে যে এটি একটি গঠন, ফে জন্য একটি alias হল: typedef struct foo foo_struct;
।
এই সমস্যা থেকে ফলশ্রুতিতে সর্বদা এনডাম টাইপডেফের অন্য একটি ভাল কারণ:
enum EnumDef
{
FIRST_ITEM,
SECOND_ITEM
};
struct StructDef
{
enum EnuumDef MyEnum;
unsigned int MyVar;
} MyStruct;
স্ট্রাক্ট ( এনু ইউ এমডিএফ) এ এনামডিফের টাইপটি লক্ষ্য করুন? এটি ত্রুটি (বা সতর্কতা) ছাড়াই সংকলন করে এবং (সি স্ট্যান্ডার্ডের আক্ষরিক ব্যাখ্যার উপর নির্ভর করে) সঠিক। সমস্যাটি হ'ল আমি কেবল আমার কাঠামোর মধ্যে একটি নতুন (খালি) গণনার সংজ্ঞা তৈরি করেছি created আমি পূর্বের সংজ্ঞা এনামডিফ ব্যবহার করে নিচ্ছি না।
টাইপডেফের সাথে একই ধরণের টাইপসের ফলে অজানা প্রকারটি ব্যবহারের জন্য একটি সংকলক ত্রুটি হতে পারে:
typedef
{
FIRST_ITEM,
SECOND_ITEM
} EnumDef;
typedef struct
{
EnuumDef MyEnum; /* compiler error (unknown type) */
unsigned int MyVar;
} StructDef;
StrructDef MyStruct; /* compiler error (unknown type) */
আমি সর্বদা টাইপডেফিং স্ট্রাক্ট এবং গণনার পক্ষে পরামর্শ দেব।
কেবল কিছু টাইপিং সংরক্ষণ করার জন্য নয় (কোনও পাং উদ্দেশ্যে নয়)), তবে এটি নিরাপদ।
enum
টাইপ হিসাবে ব্যবহার করতে নিরুৎসাহিত করা হয় , কারণ অনেক সংকলক তাদের 'ভুল' ব্যবহার করার সময় অদ্ভুত সতর্কতা নির্গত করে। উদাহরণস্বরূপ, একটি enum
থেকে 0 আরম্ভ করা একটি 'পূর্ণসংখ্যার ধ্রুবক নয় এনামে' সতর্কতা দেয়। ফরওয়ার্ড-ডিক্লেয়ারিংও enum
অনুমোদিত নয়। পরিবর্তে একটি int
(বা unsigned int
) ব্যবহার করা উচিত ।
লিনাক্স কার্নেল কোডিং শৈলী অধ্যায় 5 ব্যবহারের দুর্দান্ত উপকারিতা এবং কনস (বেশিরভাগ ক্ষেত্রে) দেয় typedef
।
দয়া করে "vps_t" এর মতো জিনিস ব্যবহার করবেন না।
এটা একটা ব্যাপার ভুল কাঠামো ও পয়েন্টার typedef জন্য ব্যবহার করতে। যখন আপনি একটি
vps_t a;
উত্সে, এর অর্থ কী?
বিপরীতে, যদি এটি বলে
struct virtual_container *a;
আপনি আসলে "এ" কী তা বলতে পারেন।
প্রচুর লোকেরা মনে করেন যে টাইপিডেফগুলি "পাঠযোগ্যতার সহায়তা করে"। তাই না। এগুলি কেবল এর জন্য দরকারী:
(ক) সম্পূর্ণ অস্বচ্ছ বস্তু (যেখানে টাইপডেফ সক্রিয়ভাবে বস্তুটি কী তা লুকানোর জন্য ব্যবহৃত হয়)।
উদাহরণ: "pte_t" ইত্যাদি অস্বচ্ছ অবজেক্টগুলি যে আপনি কেবল সঠিক অ্যাকসেসর ফাংশনগুলি ব্যবহার করে অ্যাক্সেস করতে পারবেন।
বিঃদ্রঃ! অস্পষ্টতা এবং "অ্যাক্সেসর ফাংশনগুলি" নিজের মধ্যে ভাল নয়। কারণ আমরা তাদের pte_t ইত্যাদি জিনিসের জন্য আছে সত্যিই একেবারে হয় শূন্য portably প্রবেশযোগ্য তথ্য আছে।
(খ) পূর্ণসংখ্যার ধরণগুলি সাফ করুন, যেখানে বিমূর্ততা "ইনট" বা "দীর্ঘ" কিনা তা বিভ্রান্তি এড়াতে সহায়তা করে ।
u8 / u16 / u32 পুরোপুরি সূক্ষ্ম টাইপডেফ, যদিও তারা এখানে (ডি) এর চেয়ে আরও ভাল বিভাগে ফিট করে।
বিঃদ্রঃ! আবার - এর কারণ হওয়ার দরকার আছে । যদি কিছু "স্বাক্ষরবিহীন দীর্ঘ" হয় তবে তা করার কোনও কারণ নেই
typedef unsigned long myflags_t;
তবে যদি নির্দিষ্ট পরিস্থিতিতে এটি একটি "স্বাক্ষরবিহীন অন্তর্নিহিত" হতে পারে এবং অন্য কনফিগারেশনের অধীনে "স্বাক্ষরবিহীন দীর্ঘ" হতে পারে তার কোনও স্পষ্ট কারণ আছে, তবে যেকোনো উপায়ে এগিয়ে যান এবং টাইপইডেফ ব্যবহার করুন।
(গ) যখন আপনি টাইপ-চেকিংয়ের জন্য আক্ষরিকভাবে একটি নতুন ধরণের তৈরি করতে স্পার ব্যবহার করেন ।
(ঘ) নির্দিষ্ট ব্যতিক্রমী পরিস্থিতিতে নতুন ধরণের যা স্ট্যান্ডার্ড সি 99 ধরণের সমান।
যদিও চোখ এবং মস্তিষ্ককে 'uint32_t' এর মতো মানসম্পন্ন ধরণের অভ্যস্ত হয়ে উঠতে কেবল অল্প সময়ের জন্য সময় লাগবে, কিছু লোক যাইহোক তাদের ব্যবহারে আপত্তি জানায়।
অতএব, লিনাক্স-নির্দিষ্ট 'u8 / u16 / u32 / u64' প্রকার এবং তাদের স্বাক্ষরযুক্ত সমতুল্য যা মানক ধরণের সমতুল্য, তা অনুমোদিত - যদিও সেগুলি আপনার নিজস্ব নতুন কোডে বাধ্যতামূলক নয়।
ইতিমধ্যে বিদ্যমান কোডটি সম্পাদনা করার সময় যা ইতিমধ্যে এক বা অন্য প্রকারের সেট ব্যবহার করে, আপনার সেই কোডটিতে বিদ্যমান পছন্দগুলি মেনে চলতে হবে।
(ঙ) প্রকারের ইউজারস্পেসে ব্যবহারের জন্য নিরাপদ।
কিছু নির্দিষ্ট স্ট্রাকচারে যা ইউজারস্পেসের জন্য দৃশ্যমান, আমরা C99 ধরণের প্রয়োজন পড়তে পারি না এবং উপরে 'u32' ফর্মটি ব্যবহার করতে পারি না। সুতরাং, আমরা ব্যবহারকারীর সাথে ভাগ করা সমস্ত কাঠামোতে __u32 এবং একই ধরণের ব্যবহার করি।
হতে পারে অন্যান্য ক্ষেত্রেও হতে পারে, তবে নিয়মটি সাধারণত কোনও টাইপডেফ ব্যবহার করা উচিত নয় যতক্ষণ না আপনি এই নিয়মের একটি পরিষ্কারভাবে মেলে না।
সাধারণভাবে, একটি পয়েন্টার, বা স্ট্রাক্টের এমন উপাদান রয়েছে যা যুক্তিসঙ্গতভাবে সরাসরি অ্যাক্সেস করা যায় কখনও কখনও টাইপিডেফ হওয়া উচিত নয় ।
দেখা যাচ্ছে যে এখানে বিভিন্ন উপকারিতা এবং বিপরীতে রয়েছে। তথ্যের একটি দরকারী উত্স হল "বিশেষজ্ঞ সি প্রোগ্রামিং" এর চূড়ান্ত বই ( অধ্যায় 3 )। সংক্ষেপে, সিতে আপনার একাধিক নেমস্পেস রয়েছে: ট্যাগ, প্রকার, সদস্যের নাম এবং শনাক্তকারী । typedef
কোনও প্রকারের জন্য একটি নাম উপস্থাপন করে এবং ট্যাগ নেমস্পেসে এটি সনাক্ত করে। যেমন,
typedef struct Tag{
...members...
}Type;
দুটি জিনিস সংজ্ঞায়িত ট্যাগ নেমস্পেসে একটি ট্যাগ এবং টাইপ নেমস্পেসে একটি টাইপ। সুতরাং আপনি Type myType
এবং উভয় করতে পারেন struct Tag myTagType
। মত প্রকাশ struct Type myType
বা Tag myTagType
অবৈধ Dec উপরন্তু, এই মত একটি বিবৃতিতে:
typedef Type *Type_ptr;
আমরা আমাদের টাইপ একটি পয়েন্টার সংজ্ঞায়িত। সুতরাং যদি আমরা ঘোষণা করি:
Type_ptr var1, var2;
struct Tag *myTagType1, myTagType2;
তারপর var1
, var2
এবং myTagType1
টাইপ পয়েন্টার হয় কিন্তু myTagType2
না।
উপরোক্ত বইটিতে এটি উল্লেখ করেছে যে টাইপডেফিং স্ট্রাক্টগুলি খুব কার্যকর নয় কারণ এটি কেবল প্রোগ্রামারকে স্ট্রাক্ট শব্দটি লেখার হাত থেকে বাঁচায়। তবে অন্যান্য সি প্রোগ্রামারদের মতো আমারও আপত্তি আছে। যদিও এটি কখনও কখনও কিছু নামগুলি অস্পষ্ট করে তোলে (এজন্য কার্নেলের মতো বড় কোড বেসগুলিতে এটি পরামর্শ দেওয়া হয় না) আপনি যখন সিতে পলিমারফিজম প্রয়োগ করতে চান এটি অনেক সাহায্য করে এখানে বিশদ বিবরণ দেখতে । উদাহরণ:
typedef struct MyWriter_t{
MyPipe super;
MyQueue relative;
uint32_t flags;
...
}MyWriter;
আপনি করতে পারেন:
void my_writer_func(MyPipe *s)
{
MyWriter *self = (MyWriter *) s;
uint32_t myFlags = self->flags;
...
}
সুতরাং আপনি একটি বহিরাগত সদস্য অ্যাক্সেস করতে পারেন (flags
ingালাইয়ের MyPipe
মাধ্যমে অভ্যন্তরীণ কাঠামো দ্বারা ) । আমার জন্য (struct MyWriter_ *) s;
যতবার আপনি এই জাতীয় কার্যকারিতা সম্পাদন করতে চান তার চেয়ে পুরো ধরণের কাস্ট করা কম বিভ্রান্তিকর । এই ক্ষেত্রে সংক্ষিপ্ত রেফারেন্সিং হ'ল একটি বড় বিষয়, বিশেষত যদি আপনি নিজের কোডটিতে কৌশলটি ভারীভাবে নিয়োগ করেন।
শেষ অবধি, typedef
এড প্রকারের সাথে শেষ দিকটি হ'ল ম্যাক্রোগুলির বিপরীতে এগুলি প্রসারিত করতে অক্ষমতা। উদাহরণস্বরূপ, আপনার কাছে:
#define X char[10] or
typedef char Y[10]
আপনি তারপর ঘোষণা করতে পারেন
unsigned X x; but not
unsigned Y y;
স্ট্রাক্টগুলির জন্য আমরা সত্যিই এটির যত্ন নিই না কারণ এটি স্টোরেজ স্পেসিফায়ারগুলিতে ( volatile
এবং const
) প্রযোজ্য নয় ।
MyPipe *s; MyWriter *self = (MyWriter *) s;
এবং আপনি কেবল কঠোর আলিয়াজিং ভেঙে দিয়েছেন।
typedef struct Tag{ ...members... }Type;
"দুটি জিনিস সংজ্ঞায়িত করে" এটি যথেষ্ট অর্থবহ নয়। যদি টাইপডিফ ট্যাগগুলি সংজ্ঞায়িত করে তবে এখানে 'টাইপ করুন' একটি ট্যাগও হওয়া উচিত। সত্য সংজ্ঞা 2 ট্যাগ এবং 1 ধরন সংজ্ঞায়িত (বা 2 ধরনের এবং 1 টি ট্যাগ নিশ্চিত না।) হল: struct Tag
, Tag
এবং Type
। struct Tag
অবশ্যই একটি প্রকার। Tag
একটি ট্যাগ। তবে বিভ্রান্তিটি হ'ল Type
কোনও ট্যাগ বা প্রকার
আমি মনে করি না টাইডেফের সাহায্যে এগিয়ে ঘোষণাগুলিও সম্ভব। কাঠামো, এনাম এবং ইউনিয়নের ব্যবহার যখন ফরেনডেন্ডেশনগুলি (সম্পর্কে জেনে থাকে) দ্বিমুখী হয় তখন ঘোষণাগুলি ফরওয়ার্ড করার অনুমতি দেয়।
স্টাইল: সি ++ তে টাইপডেফের ব্যবহারটি বেশ কিছুটা অর্থবোধ করে। একাধিক এবং / অথবা ভেরিয়েবল পরামিতিগুলির প্রয়োজন টেম্পলেটগুলির সাথে কাজ করার সময় এটি প্রায় প্রয়োজনীয় হতে পারে। টাইপিডেফ নামকরণ সোজা রাখতে সহায়তা করে।
সি প্রোগ্রামিং ভাষার ক্ষেত্রে তেমন নয় so টাইপডিফ ব্যবহার প্রায়শই ডেটা স্ট্রাকচারের ব্যবহারকে অবিচ্ছিন্ন করা ছাড়া কোনও উদ্দেশ্য করে না। যেহেতু কেবল {স্ট্রাক্ট (6), এনাম (4), ইউনিয়ন (5)} সংখ্যক কীস্ট্রোক একটি ডেটা টাইপ ঘোষণার জন্য ব্যবহৃত হয় সেখানে স্ট্রাক্টের এলিয়াসিংয়ের জন্য প্রায় কোনও ব্যবহার নেই। সেই ডেটা কি কোনও ইউনিয়ন বা কাঠামো টাইপ করে? সরল-সরল নন-টাইপডেফিড ঘোষণাটি আপনাকে কী ধরণের তা তাড়াতাড়ি জানতে দেয়।
লক্ষ করুন যে কীভাবে এই এলিয়াসিং ননসেন্স টাইপডিফ নিয়ে আসে লিনাক্সের কঠোর পরিহারের সাথে। ফলাফলটি একটি ন্যূনতম এবং পরিষ্কার শৈলী।
struct
সব জায়গায় পুনরাবৃত্তি করা হবে না ... টাইপেডেফ নতুন ধরণের তৈরি করুন। তুমি কি ব্যবহার কর? ধরন। এটি স্ট্রাক্ট, ইউনিয়ন বা এনাম কিনা তা আমরা যত্ন করি না , এজন্য আমরা এটি টাইপড করি।
FILE
?
আসুন আমরা বেসিকগুলি দিয়ে শুরু করি এবং আমাদের পথে কাজ করি।
কাঠামোর সংজ্ঞার উদাহরণ এখানে:
struct point
{
int x, y;
};
এখানে নামটি point
.চ্ছিক।
একটি সংজ্ঞা তার সংজ্ঞা বা তার পরে ঘোষণা করা যেতে পারে declared
সংজ্ঞা চলাকালীন ঘোষণা
struct point
{
int x, y;
} first_point, second_point;
সংজ্ঞা পরে ঘোষণা
struct point
{
int x, y;
};
struct point first_point, second_point;
এখন, সাবধানে উপরের শেষ কেসটি নোট করুন; আপনি struct point
যদি আপনার কোডের পরবর্তী সময়ে এই ধরণের তৈরি করার সিদ্ধান্ত নেন তবে আপনাকে সেই ধরণের স্ট্রাকচারগুলি ঘোষণা করতে লিখতে হবে।
প্রবেশ করুন typedef
। আপনি যদি একই ব্লুপ্রিন্ট ব্যবহার করে আপনার প্রোগ্রামের পরবর্তী সময়ে নতুন স্ট্রাকচার (কাঠামোটি একটি কাস্টম ডেটা টাইপ) তৈরির পরিকল্পনা typedef
করেন তবে এর সংজ্ঞাটির সময়কালে ব্যবহার করা ভাল ধারণা হতে পারে যেহেতু আপনি কিছু টাইপিংকে এগিয়ে নিয়ে যেতে পারবেন।
typedef struct point
{
int x, y;
} Points;
Points first_point, second_point;
আপনার কাস্টম টাইপের নামের শেষে _t প্রত্যয় ব্যবহার থেকে কোনও কিছুই আপনাকে আটকায় না তবে স্ট্যান্ডার্ড লাইব্রেরির টাইপের নাম বোঝাতে POSIX স্ট্যান্ডার্ড প্রত্যয় _t ব্যবহার সংরক্ষণ করে।
আপনি (allyচ্ছিকভাবে) কাঠামোর যে নামটি দিয়েছেন তা ট্যাগের নাম বলে এবং যেমনটি উল্লেখ করা হয়েছে, এটি নিজের মধ্যে কোনও প্রকার নয়। প্রকারটি পেতে স্ট্রাক্ট উপসর্গ প্রয়োজন।
জিটিকে + একপাশে, আমি নিশ্চিত নই যে ট্যাগের নামটি কাঠামোর ধরণে টাইপডেফের মতো সাধারণভাবে ব্যবহৃত হয়, তাই সি ++ তে যা স্বীকৃত এবং আপনি স্ট্রাক কীওয়ার্ডটি বাদ দিতে পারেন এবং ট্যাগের নামটিও টাইপের নাম হিসাবে ব্যবহার করতে পারেন:
struct MyStruct
{
int i;
};
// The following is legal in C++:
MyStruct obj;
obj.i = 7;
টাইপিডেফ কোনও কাঠামোগত একটি নির্ভরশীল ডেটা স্ট্রাকচার সরবরাহ করবে না। এটি আপনি টাইপডিফ দিয়ে করতে পারবেন না:
struct bar;
struct foo;
struct foo {
struct bar *b;
};
struct bar {
struct foo *f;
};
অবশ্যই আপনি সর্বদা যোগ করতে পারেন:
typedef struct foo foo_t;
typedef struct bar bar_t;
এর ঠিক কী আছে?
এ> ডেটা টাইপের জন্য আরও অর্থপূর্ণ প্রতিশব্দ তৈরি করার অনুমতি দিয়ে কোনও প্রোগ্রামের অর্থ এবং ডকুমেন্টেশনে একটি টাইপডিফ সহায়তা করে । তদতিরিক্ত, তারা পোর্টেবিলিটি সমস্যাগুলির বিরুদ্ধে কোনও প্রোগ্রামকে প্যারামিটারাইজ করতে সহায়তা করে (কেএন্ডআর, পিজি 147, সি প্রোগ ল্যাং)।
বি> একটি কাঠামো একটি প্রকারের সংজ্ঞা দেয় । স্ট্রোক্টস হ্যান্ডলিংয়ের সুবিধার্থে ভার্সের সংগ্রহের সুবিধাজনক গোষ্ঠীকরণের অনুমতি দেয় (কেএন্ডআর, পিজি 127, সি প্রোগ ল্যাং।) একক ইউনিট হিসাবে
সি> একটি কাঠামো টাইপফাইফিং উপরের এটিতে ব্যাখ্যা করা হয়েছে।
ডি> আমার কাছে স্ট্রাক্টগুলি হ'ল কাস্টম ধরণের বা পাত্রে বা সংগ্রহগুলি বা নামের জায়গাগুলি বা জটিল ধরণের, অন্যদিকে একটি টাইপডিফ আরও বেশি ডাকনাম তৈরি করার উপায়।
C99 টাইপএডেফ চালু হয় প্রয়োজনীয়। এটি পুরানো, তবে প্রচুর সরঞ্জাম (আলা হ্যাকর্যাঙ্ক) সি 99 এর খাঁটি সি বাস্তবায়ন হিসাবে ব্যবহার করে। এবং সেখানে টাইপিডেফের প্রয়োজন।
আমি বলছি না যে তাদের পরিবর্তন করা উচিত (সম্ভবত দুটি সি বিকল্প রয়েছে) যদি প্রয়োজনীয়তা পরিবর্তিত হয়, তবে আমরা যারা সাইটে সাক্ষাত্কারের জন্য স্টাডিং করব তারা এসএল হবে be
typedef
দেখা দরকার" " আপনি কি বোঝাতে চেয়েছেন?
C
, না C++
। ইন C
typedefs হয় 'প্রয়োজনীয়' (এবং সম্ভবত সবসময় হতে হবে)। 'আবশ্যক' যেমন রয়েছে তেমন আপনি কোনও পরিবর্তনশীল ঘোষণা করতে পারবেন না Point varName;
এবং প্রকারটি struct Point;
একটি ছাড়া সমার্থক হতে পারেন typedef struct Point Point;
।
'সি' প্রোগ্রামিং ল্যাঙ্গুয়েজে 'টাইপডিফ' কীওয়ার্ডটি কোনও বস্তুর (স্ট্রাক্ট, অ্যারে, ফাংশন..ইনাম প্রকার) নতুন নাম ঘোষণা করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আমি একটি 'স্ট্রাক্ট-এস' ব্যবহার করব। 'সি' তে আমরা প্রায়শই 'মূল' ফাংশনের বাইরে 'স্ট্রাক্ট' ঘোষণা করি। উদাহরণ স্বরূপ:
struct complex{ int real_part, img_part }COMPLEX;
main(){
struct KOMPLEKS number; // number type is now a struct type
number.real_part = 3;
number.img_part = -1;
printf("Number: %d.%d i \n",number.real_part, number.img_part);
}
প্রতিবার যখনই আমি স্ট্রাক্ট টাইপটি ব্যবহার করার সিদ্ধান্ত নেব তখন আমার এই কীওয়ার্ডটির দরকার হবে 'স্ট্রাক্ট' কিছু '' নাম '' টাইপডিফ 'কেবল সেই জাতীয় নামটির নামকরণ করবে এবং আমি যখনই চাই আমার প্রোগ্রামে নতুন নামটি ব্যবহার করতে পারি। সুতরাং আমাদের কোড হবে:
typedef struct complex{int real_part, img_part; }COMPLEX;
//now COMPLEX is the new name for this structure and if I want to use it without
// a keyword like in the first example 'struct complex number'.
main(){
COMPLEX number; // number is now the same type as in the first example
number.real_part = 1;
number.img)part = 5;
printf("%d %d \n", number.real_part, number.img_part);
}
আপনার যদি কিছু স্থানীয় অবজেক্ট (স্ট্রাক্ট, অ্যারে, মূল্যবান) থাকে যা আপনার পুরো প্রোগ্রামে ব্যবহৃত হবে তবে আপনি কেবল 'টাইপডেফ' ব্যবহার করে এটির নাম দিতে পারেন।
মোটেও, সি ভাষায়, স্ট্রাক্ট / ইউনিয়ন / এনাম হ'ল সি ভাষা প্রিপ্রসেসর প্রক্রিয়াজাতকরণের ম্যাক্রো নির্দেশনা ("# অন্তর্ভুক্ত" এবং অন্যান্যরূপে ব্যবহৃত প্রিપ્રোসেসরের সাথে ভুল করবেন না)
সুতরাং:
struct a
{
int i;
};
struct b
{
struct a;
int i;
int j;
};
কাঠামো বি এর মতো কিছু হিসাবে ব্যয় করা হয়:
struct b
{
struct a
{
int i;
};
int i;
int j;
}
এবং তাই, সংকলনের সময় এটি স্ট্যাকের মতো কিছু হিসাবে বিকশিত হয়েছিল: b: int ai int i int j
এছাড়াও স্বাবলম্বী স্ট্রাক্ট, সি প্রিপ্রোসেসর বৃত্তিকে একটি ডিক্লারেশন লুপে শেষ করতে পারেন না কেন এটি পৃথক।
টাইপডিফ হ'ল টাইপ স্পেসিফায়ার, তার অর্থ কেবল সি সংকলক এটি প্রক্রিয়া করে এবং এটি এসেম্বলারের কোড প্রয়োগকরণের অনুকূলকরণের জন্য চাইলে এটি করতে পারে। এটি প্রসেসরের মতো নির্বোধের মতো প্রকারের সদস্যকে ব্যয় করতে পারে না তবে আরও জটিল রেফারেন্স নির্মাণ অ্যালগরিদম ব্যবহার করে, সুতরাং যেমন নির্মাণ:
typedef struct a A; //anticipated declaration for member declaration
typedef struct a //Implemented declaration
{
A* b; // member declaration
}A;
অনুমোদিত এবং সম্পূর্ণ ক্রিয়ামূলক। এই প্রয়োগটি সংকলক প্রকার রূপান্তর করতেও অ্যাক্সেস দেয় এবং যখন এক্সিকিউশন থ্রেড আরম্ভিককরণ কার্যের অ্যাপ্লিকেশন ক্ষেত্রটি ছেড়ে যায় তখন কিছু বাগিং প্রভাবগুলি সরিয়ে দেয়।
এর অর্থ সি টাইপেডেফ একাকী স্ট্রাক্টের চেয়ে সি ++ শ্রেণি হিসাবে বেশি।
structs
typedef
typedef
struct
struct b
struct a *
typedef
struct
typedef