কেন আমরা প্রায়শই সি তে স্ট্রাক্ট টাইপ করব?


406

আমি নীচের মত কাঠামো সমন্বিত অনেক প্রোগ্রাম দেখেছি

typedef struct 
{
    int i;
    char k;
} elem;

elem user;

কেন এত ঘন ঘন দরকার হয়? কোন নির্দিষ্ট কারণ বা প্রযোজ্য অঞ্চল?


14
আরো পুঙ্খানুপুঙ্খ এবং সুনির্দিষ্ট উত্তর: stackoverflow.com/questions/612328/...
AbiusX

এর অসুবিধাগুলি আমি মনে করি আপনি বেনামে স্ট্রাক্টের সাথে লিঙ্ক তালিকা তৈরি করতে পারবেন না struct * ptrকারণ
কাঠামোর

9
'আরও পুঙ্খানুপুঙ্খ এবং সুনির্দিষ্ট উত্তর' হ'ল সি ++ তে স্ট্রাক্ট এবং টাইপিডেফ স্ট্রাক্টের মধ্যে পার্থক্য এবং এই অঞ্চলে সি এবং সি ++ এর মধ্যে উল্লেখযোগ্য পার্থক্য রয়েছে যা সি সম্পর্কে একটি প্রশ্নের উপযুক্ত উত্তর দেয় না
জোনাথন লেফলার

এই প্রশ্নের একটি সদৃশ টাইপডিফ স্ট্রাক্ট বনাম স্ট্রাক্ট সংজ্ঞা রয়েছে যার উত্তরের উত্তরও রয়েছে।
জোনাথন লেফলার

উত্তর:


452

গ্রেগ হিউগিল যেমন বলেছিলেন, টাইপিডেফের অর্থ আপনাকে আর 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 দেখুন । :) আমার বক্তব্যটি হ'ল এই প্রশ্নে "উচিত" সম্ভবত পাথরের উপরে সেট করা নেই।


58
আপনার বড় আকারের অক্ষরের পরে আন্ডারস্কোরযুক্ত সনাক্তকারী ব্যবহার করা উচিত নয়, সেগুলি সংরক্ষিত রয়েছে (বিভাগ 7.1.3 অনুচ্ছেদ 1 দেখুন)। যদিও সমস্যাটি বেশিরভাগ ক্ষেত্রেই হওয়ার সম্ভাবনা নেই, আপনি যখন এটি ব্যবহার করেন তখন এটি প্রযুক্তিগতভাবে অপরিজ্ঞাত আচরণ (7.1.3 অনুচ্ছেদ 2)।
ড্রিমলাক্স

16
@ ড্রিমলাক্স: যদি এটি অন্যদের কাছে পরিষ্কার না হয় তবে এটি কেবল একটি আন্ডারস্কোর এবং একটি উচ্চতর কেস দিয়ে আপনার পরিচয় করানো শুরু করবেন; আপনি এটি একটি সনাক্তকারী এর মাঝখানে ব্যবহার করতে পারেন।
ব্রায়ানমার্ম

12
এটি আকর্ষণীয় যে এখানে দেওয়া উদাহরণটি (যেখানে টাইপিডেফ "সমস্ত জায়গায়" স্ট্রাক্ট "" ব্যবহার করা বাধা দেয়) টাইপডেফ ছাড়াই আসলে একই কোডের চেয়ে দীর্ঘতর, কারণ এটি "স্ট্রাক্ট" শব্দের ঠিক একটি ব্যবহার সংরক্ষণ করে। বিমূর্ততার স্মিডজেন অতিরিক্ত বিরলতার সাথে খুব কমই অনুকূল তুলনা করে।
উইলিয়াম পার্সেল

7
@ রিরিটো ফাই , সি 99 খসড়ার পৃষ্ঠা 166, আন্ডারস্কোর এবং বড় হাতের অক্ষর বা অন্য কোনও আন্ডারস্কোর দিয়ে শুরু হওয়া সমস্ত পরিচয় সর্বদা যে কোনও ব্যবহারের জন্য সংরক্ষিত। এবং সমস্ত সনাক্তকারী যা আন্ডারস্কোর দিয়ে শুরু হয় সর্বদা সাধারণ এবং ট্যাগ নাম উভয় জায়গাতেই লে স্কোপ সহ সনাক্তকারী হিসাবে ব্যবহারের জন্য সংরক্ষিত থাকে।
e2-e4

10
আকর্ষণীয়ভাবে যথেষ্ট, লিনাক্স কার্নেল কোডিং গাইডলাইনস বলছে যে টাইপডেফগুলি
ডক

206

কত লোক এই ভুল করে তা অবাক করে দেয়। অনুগ্রহ করে সি তে টাইপড স্ট্রাকগুলি ব্যবহার করবেন না, এটি অকারণে গ্লোবাল নেমস্পেসকে দূষিত করে যা সাধারণত বড় সি প্রোগ্রামগুলিতে ইতিমধ্যে খুব দূষিত।

এছাড়াও, ট্যাগ নাম ছাড়া টাইপফাইড স্ট্রাইকগুলি শিরোনাম ফাইলগুলির মধ্যে সম্পর্কের ক্রমকে অর্পণ করার অপ্রয়োজনীয় চাপিয়ে দেওয়ার একটি বড় কারণ।

বিবেচনা:

#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);

নাম স্পেসগুলি পৃথক হওয়ায়, তার কাঠামোর নামের সাথে ভেরিয়েবলের নামকরণে কোনও বিরোধ নেই।

যদি আমাকে আপনার কোড বজায় রাখতে হয় তবে আমি আপনার টাইপডেফ স্ট্রাক্টগুলি সরিয়ে দেব।


37
আরও আশ্চর্যের বিষয় হ'ল এই উত্তরটি দেওয়ার পরে 13 মাস পরে, আমি প্রথম এটির উপরে উঠে এসেছি! টাইপডেফিং স্ট্রাক্টস সি-এর অন্যতম বৃহৎ গালাগাল এবং এর লিখিত কোডে কোনও স্থান নেই। টাইপিডেফ সংশ্লেষিত ফাংশন পয়েন্টার প্রকারগুলি ডি-ওফফেস্কেটিংয়ের জন্য দরকারী এবং সত্যিকার অর্থে অন্য কোনও কার্যকর উদ্দেশ্যে কাজ করে না।
উইলিয়াম পার্সেল 25'12

28
পিটার ভ্যান ডের লিন্ডেন তাঁর আলোকিত বই "বিশেষজ্ঞ সি প্রোগ্রামিং - ডিপ সি সিক্রেটস" তে টাইপডেফিং স্ট্রাক্টের বিরুদ্ধেও মামলা করেছেন। সংক্ষেপটি হ'ল: আপনি জানতে চান যে কোনও কিছু কাঠামো বা ইউনিয়ন, এটি লুকান না ID
জেনস

34
লিনাক্স কার্নেল কোডিং স্টাইল স্পষ্টভাবে টাইপফিং স্ট্রাক্ট নিষিদ্ধ করে। অধ্যায় 5: টাইপিডেফস: " কাঠামো এবং পয়েন্টারগুলির জন্য টাইপডেফ ব্যবহার করা ভুল " " kernel.org/doc/ ডকুমেন্টেশন
কোডিং

63
"স্ট্রাক্ট" টাইপ করে বারবার কী উপকার পাওয়া যায়? এবং দূষণের কথা বললে, আপনি কেন বিশ্বব্যাপী নেমস্পেসে একই নামের একটি স্ট্রাক্ট এবং একটি ফাংশন / ভেরিয়েবল / টাইপিডেফ রাখতে চান (যদি না এটি একই ফাংশনের জন্য টাইপডেফ হয়)? নিরাপদ প্যাটার্নটি ব্যবহার করা typedef struct X { ... } X। আপনি সংক্ষিপ্ত ফর্মটি Xসংজ্ঞাটি যেখানেই সংজ্ঞাটি উপলভ্য পাওয়া যায় তা ব্যবহার করতে পারেন, তবে তবুও ফরোয়ার্ড-ডিক্লেয়ার এবং struct Xইচ্ছামত ব্যবহার করতে পারেন ।
পাভেল মিনায়েভ

7
আমি ব্যক্তিগতভাবে খুব কমই যদি কখনও টাইপিডেফ ব্যবহার করি তবে আমি বলব না যে অন্য লোকেরা এটি ব্যবহার করবেন না, এটি কেবল আমার স্টাইল নয়। আমি একটি ভেরিয়েবল টাইপের আগে একটি স্ট্রাক্ট দেখতে চাই তাই আমি সরাসরি এটির স্ট্রাক্ট জানি। আর্গুমেন্ট টাইপ করা সহজ কিছুটা খোঁড়া, একক অক্ষরযুক্ত ভেরিয়েবল থাকা টাইপ করাও সহজ, এছাড়াও আজকাল কোথাও কোথাও কাঠামো টাইপ করা কতটা কঠিন তা স্বয়ংক্রিয় পরিসমাপ্তি সহ।
নাথান ডে

138

ড্যান সাকসের একটি পুরানো নিবন্ধ থেকে ( 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এ নামটি গোপন করার সাথে একটি ত্রুটি হয়ে যায় যা সংকলক আপনাকে সম্ভাব্য সমস্যার কোনও গোপন উত্সের পরিবর্তে বলে দেয়।


2
যেখানে ট্যাগ নামটি নন-ট্যাগ নামের সাথে একই (পসিক্স বা ইউনিক্স) প্রোগ্রামে রয়েছে তার একটি উদাহরণ int stat(const char *restrict path, struct stat *restrict buf)statসাধারণ নাম জায়গাতে এবং struct statট্যাগ নামের জায়গাতে আপনার একটি ফাংশন রয়েছে ।
জোনাথন লেফলার

2
আপনার বক্তব্য, এসএস; // ত্রুটি .... এটি ভুল কাজ করে। আমি আপনার বক্তব্যটি বোঝাতে চাইছি যে "
টাইপিডেফ

63

একটি ব্যবহার typedefএড়াতে লিখতে থাকার structপ্রত্যেক সময় আপনি যে ধরনের একটি ভেরিয়েবল ডিক্লেয়ার:

struct elem
{
 int i;
 char k;
};
elem user; // compile error!
struct elem user; // this is correct

2
ঠিক আছে আমাদের সি ++ তে সমস্যা হচ্ছে না। তবে কেন কেউ সি এর কম্পাইলার থেকে সেই ত্রুটি অপসারণ করবেন না এবং এটিকে সি ++ এর মতো করুন ok ঠিক আছে সি ++ এর কিছু আলাদা অ্যাপ্লিকেশন অঞ্চল রয়েছে এবং তাই এটির উন্নত বৈশিষ্ট্য রয়েছে ut তবে আমরা কিছু পরিবর্তন না করেই সিটিতে তাদের উত্তরাধিকারী হতে পারি না? আসল সি?
মনোজ সন্দেহভাজন

4
মনোজ, ট্যাগ নাম ("স্ট্রাক্ট foo") প্রয়োজনীয় যখন আপনি নিজের মতো করে উল্লেখ করা স্ট্রাক্ট সংজ্ঞায়িত করতে পারেন। যেমন একটি লিঙ্কযুক্ত তালিকার "পরবর্তী" পয়েন্টার। আরও উল্লেখযোগ্য বিষয় হল, সংকলকটি স্ট্যান্ডার্ডকে প্রয়োগ করে এবং মানকটি এটি করতে বলে।
মাইকেল কারম্যান

41
এটি সি সংকলকের কোনও ত্রুটি নয়, এটি ডিজাইনের একটি অংশ। তারা এটি সি ++ এর জন্য বদলেছে, যা আমি মনে করি জিনিসগুলি সহজ করে তোলে, তবে এর অর্থ এই নয় যে সি এর আচরণটি ভুল।
হার্মেস

5
দুর্ভাগ্যক্রমে অনেক 'প্রোগ্রামার' একটি কাঠামো সংজ্ঞায়িত করে তারপরে কিছু 'অসম্পৃক্ত' নাম দিয়ে টাইপ করেন (যেমন স্ট্রাইক মাইস্ট্রাক্ট ...; টাইপডেফ স্ট্রাইক মাইস্ট্রাক্ট সুসান *; প্রায় সব ক্ষেত্রেই টাইপডেফ কোডের আঁকড়ে ধরার কিছুই না করে, আসল সংজ্ঞাটি লুকিয়ে রাখেন একটি পরিবর্তনশীল / পরামিতি, এবং
কোডটির

1
@ ইউজার ৩29২২৪৯৯ আমি আপনার সাথে একমত হই যে উল্লিখিত প্রোগ্রামিং স্টাইলটি ভয়াবহ তবে এটি সাধারণভাবে আইআরএন কাঠামোকে অবজ্ঞার কারণ নয় typedef। আপনি করতে পারেন typedef struct foo foo;। অবশ্যই structমূলশব্দটির আরও বেশি প্রয়োজন নেই যা দরকারী ইঙ্গিত হতে পারে যে টাইপ ওরফে আমরা যে কাঠামোটি দেখি তা কোনও কাঠামোর জন্য একটি নাম তবে এটি সাধারণত খারাপ নয়। একটি ক্ষেত্রে বিবেচনা যেখানে ফলে টাইপ ওরফে এর আইডেন্টিফায়ার typedefইঙ্গিত করে যে এটি একটি গঠন, ফে জন্য একটি alias হল: typedef struct foo foo_struct;
রবার্টস

38

এই সমস্যা থেকে ফলশ্রুতিতে সর্বদা এনডাম টাইপডেফের অন্য একটি ভাল কারণ:

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) */

আমি সর্বদা টাইপডেফিং স্ট্রাক্ট এবং গণনার পক্ষে পরামর্শ দেব।

কেবল কিছু টাইপিং সংরক্ষণ করার জন্য নয় (কোনও পাং উদ্দেশ্যে নয়)), তবে এটি নিরাপদ।


1
আরও খারাপ, আপনার টাইপও হয়ত অন্য কোনও ট্যাগের সাথে মিলে যায়। কোনও স্ট্রাক্টের ক্ষেত্রে এটি পুরো প্রোগ্রামটি সঠিকভাবে সংকলন এবং রানটাইম অপরিজ্ঞাত আচরণের ফলে আসতে পারে।
এমএম

3
এই সংজ্ঞা: 'টাইপিডেফ {FIRST_ITEM, SECOND_ITEM} এনামডিফ;' একটি এনাম সংজ্ঞা দেয় না। আমি শত শত বিশাল প্রোগ্রাম লিখেছি এবং অন্যেরা লিখেছেন এমন প্রোগ্রামগুলির রক্ষণাবেক্ষণের জন্য দুর্ভাগ্য হয়েছিল। অভিজ্ঞতার শক্ত হাত থেকে, স্ট্রাক্টে টাইপিডেফ ব্যবহার করা কেবল সমস্যার দিকে পরিচালিত করে। আশা করি প্রোগ্রামারটি এতটা প্রতিবন্ধী নয় যে তারা যখন কোনও কাঠামোর উদাহরণটি ঘোষণা করে তাদের একটি পূর্ণ সংজ্ঞা টাইপ করতে সমস্যা হয়। সি বেসিক নয়, সুতরাং আরও কিছু চরিত্র টাইপ করা প্রোগ্রামটির ক্রিয়াকলাপের জন্য ক্ষতিকারক নয়।
ব্যবহারকারী 362929249

2
নিখুঁত ন্যূনতম সংখ্যার চেয়ে বেশি সংখ্যার চেয়ে বেশি টাইপ করার ক্ষেত্রে যারা ঘৃণা বোধ করে তাদের জন্য, আমি এমন কিছু গ্রুপে যোগদানের পরামর্শ দিতে পারি যা ন্যূনতম সংখ্যার কীস্ট্রোকের সাথে অ্যাপ্লিকেশন লেখার চেষ্টা করে। কোনও কাজের পরিবেশে কেবল তাদের নতুন 'দক্ষতা' ব্যবহার করবেন না, বিশেষত এমন একটি পরিবেশের পরিবেশ যা কঠোরভাবে পিয়ারের পর্যালোচনা সম্পাদন করে
ব্যবহারকারী 362929249

দ্রষ্টব্য, সাধারণত এটি enumটাইপ হিসাবে ব্যবহার করতে নিরুৎসাহিত করা হয় , কারণ অনেক সংকলক তাদের 'ভুল' ব্যবহার করার সময় অদ্ভুত সতর্কতা নির্গত করে। উদাহরণস্বরূপ, একটি enumথেকে 0 আরম্ভ করা একটি 'পূর্ণসংখ্যার ধ্রুবক নয় এনামে' সতর্কতা দেয়। ফরওয়ার্ড-ডিক্লেয়ারিংও enumঅনুমোদিত নয়। পরিবর্তে একটি int(বা unsigned int) ব্যবহার করা উচিত ।
yyny

5
এই উদাহরণটি সংকলন করে না, আমি এটিরও আশা করব না। সংকলন ডিবাগ / টেস্ট.ও টেস্ট। কোড: 10: 17: ত্রুটি: ক্ষেত্রটির 'enum EnuumDef' enuumDef MyEnum অসম্পূর্ণ টাইপ রয়েছে; .c test.c: 10: 8: দ্রষ্টব্য: 'Enum EnuumDef' enum EnuumDef MyEnum এর অগ্রিম ঘোষণা; ^ 1 ত্রুটি উত্পন্ন হয়েছে। gnuc, std = c99 সহ।
নাটোরোজ

30

লিনাক্স কার্নেল কোডিং শৈলী অধ্যায় 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 এবং একই ধরণের ব্যবহার করি।

হতে পারে অন্যান্য ক্ষেত্রেও হতে পারে, তবে নিয়মটি সাধারণত কোনও টাইপডেফ ব্যবহার করা উচিত নয় যতক্ষণ না আপনি এই নিয়মের একটি পরিষ্কারভাবে মেলে না।

সাধারণভাবে, একটি পয়েন্টার, বা স্ট্রাক্টের এমন উপাদান রয়েছে যা যুক্তিসঙ্গতভাবে সরাসরি অ্যাক্সেস করা যায় কখনও কখনও টাইপিডেফ হওয়া উচিত নয়


4
'অস্পষ্টতা এবং "অ্যাকসেসর ফাংশনগুলি" নিজের মধ্যে ভাল নয়'। কেউ ব্যাখ্যা করতে পারেন কেন? আমি মনে করি তথ্য গোপন এবং এনক্যাপসুলেশন খুব ভাল ধারণা হবে।
ইয়াওয়ার

5
@ ইয়াওয়ার আমি এই দস্তাবেজটি কেবল পড়েছি এবং ঠিক একই ধারণা ছিল। অবশ্যই, সি বস্তু ভিত্তিক নয়, তবে বিমূর্ততা এখনও একটি জিনিস।
বাল্ড্রিক ১৮

12

দেখা যাচ্ছে যে এখানে বিভিন্ন উপকারিতা এবং বিপরীতে রয়েছে। তথ্যের একটি দরকারী উত্স হল "বিশেষজ্ঞ সি প্রোগ্রামিং" এর চূড়ান্ত বই ( অধ্যায় 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) প্রযোজ্য নয় ।


1
MyPipe *s; MyWriter *self = (MyWriter *) s;এবং আপনি কেবল কঠোর আলিয়াজিং ভেঙে দিয়েছেন।
জোনাথন রেইনার্ট

: @JonathonReinhart এটা উদাহরণস্বরূপ কিভাবে অতিশয় কাস্ট-খুশি জিটিকে + এটি প্রায় কাজ, কিভাবে এই এড়ানো যায় উল্লেখ করতে অর্থবোধক হবে bugzilla.gnome.org/show_bug.cgi?id=140722 / mail.gnome.org/archives/gtk -ড্যাভেল-লিস্ট / 2004-এপ্রিল / msg00196.html
আন্ডারস্কোর_ডি

"টাইপিডেফ একটি প্রকারের জন্য একটি উপনাম প্রবর্তন করে এবং ট্যাগ নেমস্পেসে এটি সনাক্ত করে Name যথা" typedef struct Tag{ ...members... }Type; "দুটি জিনিস সংজ্ঞায়িত করে" এটি যথেষ্ট অর্থবহ নয়। যদি টাইপডিফ ট্যাগগুলি সংজ্ঞায়িত করে তবে এখানে 'টাইপ করুন' একটি ট্যাগও হওয়া উচিত। সত্য সংজ্ঞা 2 ট্যাগ এবং 1 ধরন সংজ্ঞায়িত (বা 2 ধরনের এবং 1 টি ট্যাগ নিশ্চিত না।) হল: struct Tag, Tagএবং Typestruct Tagঅবশ্যই একটি প্রকার। Tagএকটি ট্যাগ। তবে বিভ্রান্তিটি হ'ল Typeকোনও ট্যাগ বা প্রকার
কিওয়ারটিজউ 11:38

12

আমি মনে করি না টাইডেফের সাহায্যে এগিয়ে ঘোষণাগুলিও সম্ভব। কাঠামো, এনাম এবং ইউনিয়নের ব্যবহার যখন ফরেনডেন্ডেশনগুলি (সম্পর্কে জেনে থাকে) দ্বিমুখী হয় তখন ঘোষণাগুলি ফরওয়ার্ড করার অনুমতি দেয়।

স্টাইল: সি ++ তে টাইপডেফের ব্যবহারটি বেশ কিছুটা অর্থবোধ করে। একাধিক এবং / অথবা ভেরিয়েবল পরামিতিগুলির প্রয়োজন টেম্পলেটগুলির সাথে কাজ করার সময় এটি প্রায় প্রয়োজনীয় হতে পারে। টাইপিডেফ নামকরণ সোজা রাখতে সহায়তা করে।

সি প্রোগ্রামিং ভাষার ক্ষেত্রে তেমন নয় so টাইপডিফ ব্যবহার প্রায়শই ডেটা স্ট্রাকচারের ব্যবহারকে অবিচ্ছিন্ন করা ছাড়া কোনও উদ্দেশ্য করে না। যেহেতু কেবল {স্ট্রাক্ট (6), এনাম (4), ইউনিয়ন (5)} সংখ্যক কীস্ট্রোক একটি ডেটা টাইপ ঘোষণার জন্য ব্যবহৃত হয় সেখানে স্ট্রাক্টের এলিয়াসিংয়ের জন্য প্রায় কোনও ব্যবহার নেই। সেই ডেটা কি কোনও ইউনিয়ন বা কাঠামো টাইপ করে? সরল-সরল নন-টাইপডেফিড ঘোষণাটি আপনাকে কী ধরণের তা তাড়াতাড়ি জানতে দেয়।

লক্ষ করুন যে কীভাবে এই এলিয়াসিং ননসেন্স টাইপডিফ নিয়ে আসে লিনাক্সের কঠোর পরিহারের সাথে। ফলাফলটি একটি ন্যূনতম এবং পরিষ্কার শৈলী।


10
পরিষ্কার structসব জায়গায় পুনরাবৃত্তি করা হবে না ... টাইপেডেফ নতুন ধরণের তৈরি করুন। তুমি কি ব্যবহার কর? ধরন। এটি স্ট্রাক্ট, ইউনিয়ন বা এনাম কিনা তা আমরা যত্ন করি না , এজন্য আমরা এটি টাইপড করি।
GManNickG

13
না, আমরা কি গ্রাহ্য যদি এটা একটি struct বা ইউনিয়নের একজন enum বা কিছু পারমাণবিক টাইপ বনাম। আপনি কোনও পূর্ণসংখ্যা বা একটি নির্দেশকের কাছে স্ট্রাক্ট (বা অন্য কোনও প্রকারের জন্য) জোর করতে পারবেন না, যা আপনাকে মাঝে মাঝে কিছু প্রসঙ্গ সংরক্ষণ করতে হয়। চারপাশে 'স্ট্রাক্ট' বা 'ইউনিয়ন' কীওয়ার্ড থাকার কারণে যুক্তির লোকাল উন্নতি হয়। কেউ বলে না আপনার কাঠামোর ভিতরে কী আছে তা জানা দরকার need
বার্ড জেন্ড্রিসেক

1
@ বারেন্ডজেন্ড্রিসেক: স্ট্রাক্ট এবং ইউনিয়নগুলি অন্যান্য ধরণের থেকে পৃথক, তবে ক্লায়েন্ট কোডগুলি কি এই দুটি জিনিস (স্ট্রাক্ট বা ইউনিয়ন) এর মতো কিছু সম্পর্কে যত্ন নেওয়া উচিত FILE?
সুপারক্যাট

4
@ সুপের্যাট ফাইল ফাইল টাইপফের একটি ভাল ব্যবহার। আমি মনে করি যে টাইপিডেফ অতিরিক্ত ব্যবহার করা হয়েছে , এটি ভাষার ভুল ব্যবহার নয়। আইএমএইচও প্রত্যেকটির জন্য টাইপিডেফ ব্যবহার করা হচ্ছে "অনুমানমূলক ওভারজেনারালিটি" কোডের গন্ধ। লক্ষ্য করুন যে আপনি ভেরিয়েবলগুলি ফাইল * foo হিসাবে ঘোষণা করেন, কখনও কখনও ফাইল ফাইল হিসাবে নয়। আমার কাছে এটি গুরুত্বপূর্ণ।
বার্ড জেন্ড্রিসেক

2
@ সুপের্যাট: "যদি ফাইল-শনাক্তকরণের ভেরিয়েবলগুলি ফাইলের পরিবর্তে ফাইল ফাইলের হয় * ..." তবে টাইপডেফগুলি যে দ্ব্যর্থহীনভাবে সক্ষম করে তা ঠিক এটিই! আমরা কেবল একটি ফাইল নেওয়ার জন্য ফপেন করতে ব্যবহৃত হয়েছি তাই এটি সম্পর্কে আমরা কোনও হতাশাবোধ করি না, তবে প্রতিবার আপনি টাইপডেফ যোগ করার সময় আপনি আরও একটি জ্ঞানীয় ওভারহেড প্রবর্তন করছেন: এই API টি কী foo_t আরগ বা foo_t * চায়? স্পষ্টত স্পষ্টভাবে 'কাঠামো' বহন করা যুক্তির স্থানীয়ত্বকে উন্নত করে, যদি ফাংশন সংজ্ঞা অনুযায়ী আরও কয়েকটি অক্ষরের ব্যয় হয়।
বার্ড জেন্ড্রিসেক

4

আসুন আমরা বেসিকগুলি দিয়ে শুরু করি এবং আমাদের পথে কাজ করি।

কাঠামোর সংজ্ঞার উদাহরণ এখানে:

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 ব্যবহার সংরক্ষণ করে।


3

আপনি (allyচ্ছিকভাবে) কাঠামোর যে নামটি দিয়েছেন তা ট্যাগের নাম বলে এবং যেমনটি উল্লেখ করা হয়েছে, এটি নিজের মধ্যে কোনও প্রকার নয়। প্রকারটি পেতে স্ট্রাক্ট উপসর্গ প্রয়োজন।

জিটিকে + একপাশে, আমি নিশ্চিত নই যে ট্যাগের নামটি কাঠামোর ধরণে টাইপডেফের মতো সাধারণভাবে ব্যবহৃত হয়, তাই সি ++ তে যা স্বীকৃত এবং আপনি স্ট্রাক কীওয়ার্ডটি বাদ দিতে পারেন এবং ট্যাগের নামটিও টাইপের নাম হিসাবে ব্যবহার করতে পারেন:


    struct MyStruct
    {
      int i;
    };

    // The following is legal in C++:
    MyStruct obj;
    obj.i = 7;


1

টাইপিডেফ কোনও কাঠামোগত একটি নির্ভরশীল ডেটা স্ট্রাকচার সরবরাহ করবে না। এটি আপনি টাইপডিফ দিয়ে করতে পারবেন না:

struct bar;
struct foo;

struct foo {
    struct bar *b;
};

struct bar {
    struct foo *f;
};

অবশ্যই আপনি সর্বদা যোগ করতে পারেন:

typedef struct foo foo_t;
typedef struct bar bar_t;

এর ঠিক কী আছে?


1

এ> ডেটা টাইপের জন্য আরও অর্থপূর্ণ প্রতিশব্দ তৈরি করার অনুমতি দিয়ে কোনও প্রোগ্রামের অর্থ এবং ডকুমেন্টেশনে একটি টাইপডিফ সহায়তা করে । তদতিরিক্ত, তারা পোর্টেবিলিটি সমস্যাগুলির বিরুদ্ধে কোনও প্রোগ্রামকে প্যারামিটারাইজ করতে সহায়তা করে (কেএন্ডআর, পিজি 147, সি প্রোগ ল্যাং)।

বি> একটি কাঠামো একটি প্রকারের সংজ্ঞা দেয় । স্ট্রোক্টস হ্যান্ডলিংয়ের সুবিধার্থে ভার্সের সংগ্রহের সুবিধাজনক গোষ্ঠীকরণের অনুমতি দেয় (কেএন্ডআর, পিজি 127, সি প্রোগ ল্যাং।) একক ইউনিট হিসাবে

সি> একটি কাঠামো টাইপফাইফিং উপরের এটিতে ব্যাখ্যা করা হয়েছে।

ডি> আমার কাছে স্ট্রাক্টগুলি হ'ল কাস্টম ধরণের বা পাত্রে বা সংগ্রহগুলি বা নামের জায়গাগুলি বা জটিল ধরণের, অন্যদিকে একটি টাইপডিফ আরও বেশি ডাকনাম তৈরি করার উপায়।


0

C99 টাইপএডেফ চালু হয় প্রয়োজনীয়। এটি পুরানো, তবে প্রচুর সরঞ্জাম (আলা হ্যাকর্যাঙ্ক) সি 99 এর খাঁটি সি বাস্তবায়ন হিসাবে ব্যবহার করে। এবং সেখানে টাইপিডেফের প্রয়োজন।

আমি বলছি না যে তাদের পরিবর্তন করা উচিত (সম্ভবত দুটি সি বিকল্প রয়েছে) যদি প্রয়োজনীয়তা পরিবর্তিত হয়, তবে আমরা যারা সাইটে সাক্ষাত্কারের জন্য স্টাডিং করব তারা এসএল হবে be


2
"C99 এ typedefদেখা দরকার" " আপনি কি বোঝাতে চেয়েছেন?
জুলিয়ান লোপেজ

প্রশ্নটি সম্পর্কে C, না C++। ইন Ctypedefs হয় 'প্রয়োজনীয়' (এবং সম্ভবত সবসময় হতে হবে)। 'আবশ্যক' যেমন রয়েছে তেমন আপনি কোনও পরিবর্তনশীল ঘোষণা করতে পারবেন না Point varName;এবং প্রকারটি struct Point;একটি ছাড়া সমার্থক হতে পারেন typedef struct Point Point;
yyny

0

'সি' প্রোগ্রামিং ল্যাঙ্গুয়েজে 'টাইপডিফ' কীওয়ার্ডটি কোনও বস্তুর (স্ট্রাক্ট, অ্যারে, ফাংশন..ইনাম প্রকার) নতুন নাম ঘোষণা করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, আমি একটি 'স্ট্রাক্ট-এস' ব্যবহার করব। 'সি' তে আমরা প্রায়শই 'মূল' ফাংশনের বাইরে 'স্ট্রাক্ট' ঘোষণা করি। উদাহরণ স্বরূপ:

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);

}

আপনার যদি কিছু স্থানীয় অবজেক্ট (স্ট্রাক্ট, অ্যারে, মূল্যবান) থাকে যা আপনার পুরো প্রোগ্রামে ব্যবহৃত হবে তবে আপনি কেবল 'টাইপডেফ' ব্যবহার করে এটির নাম দিতে পারেন।


-2

মোটেও, সি ভাষায়, স্ট্রাক্ট / ইউনিয়ন / এনাম হ'ল সি ভাষা প্রিপ্রসেসর প্রক্রিয়াজাতকরণের ম্যাক্রো নির্দেশনা ("# অন্তর্ভুক্ত" এবং অন্যান্যরূপে ব্যবহৃত প্রিપ્રোসেসরের সাথে ভুল করবেন না)

সুতরাং:

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;

অনুমোদিত এবং সম্পূর্ণ ক্রিয়ামূলক। এই প্রয়োগটি সংকলক প্রকার রূপান্তর করতেও অ্যাক্সেস দেয় এবং যখন এক্সিকিউশন থ্রেড আরম্ভিককরণ কার্যের অ্যাপ্লিকেশন ক্ষেত্রটি ছেড়ে যায় তখন কিছু বাগিং প্রভাবগুলি সরিয়ে দেয়।

এর অর্থ সি টাইপেডেফ একাকী স্ট্রাক্টের চেয়ে সি ++ শ্রেণি হিসাবে বেশি।


3
স্ব-রেফারেন্সিয়াল স্ট্রাইক আদৌ রাখা মোটেই কঠিন নয়। સ્ટ্রাক্ট foo {স্ট্রাক্ট foo * পরবর্তী; int জিনিস; }
বারান্দ জেন্দ্রিসেক

4
...কি? এবং এর রেজোলিউশন বর্ণনা করার জন্য প্রিপ্রসেসর বলা যথেষ্ট খারাপ, তবে আপনার বাকী লেখাটি এতটাই বিভ্রান্তিকর যে এর থেকে কোনও বার্তা পাওয়া আমার পক্ষে কঠিন। আমি কেবল একটা বিষয় বলতে পারেন, যদিও, যে আপনার ধারণা যে একটি অ হয় ঘ করতে পারবে না এগিয়ে-ঘোষিত অথবা একটি অস্বচ্ছ (পয়েন্টার) সদস্য হিসাবে ব্যবহার করা যেতে সম্পূর্ণভাবে মিথ্যা। আপনার 1 ম উদাহরণে, তুচ্ছভাবে একটি থাকতে পারে , প্রয়োজন নেই। যে দাবিগুলি কেবল ম্যাক্রো-প্রসারণের বোবা টুকরো, এবং এটি তাদেরকে বিপ্লবী নতুন ক্ষমতা দেয়, তা বেদনাদায়কভাবে ভুলstructstypedeftypedefstructstruct bstruct a *typedefstructtypedef
আন্ডারস্কোর_
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.