আকারে সি সিঙ্গল স্ট্রাক্ট সদস্য


109

আমি অন্য একটি কাঠামোর উপর নির্ভরশীল এমন স্ট্রাক্ট ঘোষণা করার চেষ্টা করছি। আমি sizeofনিরাপদ / পেডেন্টিক হতে ব্যবহার করতে চাই ।

typedef struct _parent
{
  float calc ;
  char text[255] ;
  int used ;
} parent_t ;

এখন আমি এমন একটি স্ট্রাকচার ঘোষণা করতে চাই child_tযার আকারটি সমান parent_t.text

কিভাবে আমি এটি করতে পারব? (নীচে সিউডো-কোড।)

typedef struct _child
{
  char flag ;
  char text[sizeof(parent_t.text)] ;
  int used ;
} child_t ;

আমি parent_tএবং এর সাথে কয়েকটি ভিন্ন উপায়ে চেষ্টা করেছি struct _parent, তবে আমার সংকলক গ্রহণ করবে না।

কৌশল হিসাবে, এটি কাজ করে বলে মনে হচ্ছে:

parent_t* dummy ;
typedef struct _child
{
  char flag ;
  char text[sizeof(dummy->text)] ;
  int used ;
} child_t ;

child_tএটি ব্যবহার ছাড়া ঘোষণা করা সম্ভব dummy?

উত্তর:


202

যদিও বাফারের #defineআকারটিকে একটির সাথে সংজ্ঞায়িত করা এটির একটি মূio় উপায়, অন্যটি হ'ল ম্যাক্রোটি ব্যবহার করা হবে:

#define member_size(type, member) sizeof(((type *)0)->member)

এবং এটি এর মতো ব্যবহার করুন:

typedef struct
{
    float calc;
    char text[255];
    int used;
} Parent;

typedef struct
{
    char flag;
    char text[member_size(Parent, text)];
    int used;
} Child;

আমি আসলে কিছুটা অবাক হয়েছি যা sizeof((type *)0)->member)ধ্রুবক প্রকাশ হিসাবেও অনুমোদিত। দুর্দান্ত জিনিস।


2
বাহ, আমি আকার ((টাইপ *) 0) -> সদস্য) কাজ জানি না। এখন আমার ডেভ মেশিনে নেই, তবে এটি কি সমস্ত সংকলকগুলির জন্য কাজ করে? জয়ের জন্য ধন্যবাদ
গঙ্গাধর

4
@ গঙ্গাধর: হ্যাঁ, এটি সমস্ত সংকলকগুলির জন্য কাজ করে। অপারেন্ডকে sizeofমূল্যায়ন করা হয় না, সুতরাং নাল পয়েন্টারটিকে ডিফেরেন্স করার সাথে কোনও সমস্যা নেই (কারণ এটি প্রকৃতপক্ষে অবচয় নয়)।
জেমস ম্যাকনেলিস

4
বিস্ময়কর? এর সরল সি 89, <stddef.h> "অফসেটফ" এর বাস্তবায়ন দেখুন বা একই বাস্তবায়ন eetimes.com/design/other/4024941/…
ব্যবহারকারী 411313

1
@ জাভিয়ারজিফ্রে: এখানে, আকারটি ((টাইপ *) 0) -> সদস্যের ধরণের অনুমান করে এবং সেই ধরণের আকার প্রদান করে। ((টাইপ *) 0) হ'ল স্ট্রাক্ট টাইপের একটি নাল পয়েন্টার। ptr-> সদস্য (সংকলন সময়ে) একটি অভিব্যক্তি যা এর ধরনের সদস্য এর ধরনের হয়। আকারের কোডটি কখনও চলবে না (যদি এটি হয় তবে প্রোগ্রামটি সেগফল্ট হবে!)। আকারের মধ্যে শুধুমাত্র মানের ধরণটি দেখা হয়।
জোয়ে অ্যাডামস

1
অফসেট_- এর উইকিপিডিয়া পৃষ্ঠাটি সি স্ট্যান্ডার্ড অনুযায়ী এটি অপরিজ্ঞাত আচরণ হিসাবে নোট করে, তাই আমি সমস্ত সংকলকগুলির সাথে কাজ করে তাতে বাজি ধরব না।
গ্রামীণ

30

আমি এখনই আমার বিকাশ মেশিনে নেই, তবে আমি মনে করি আপনি নিম্নলিখিতগুলির মধ্যে একটি করতে পারেন:

sizeof(((parent_t *)0)->text)

sizeof(((parent_t){0}).text)


সম্পাদনা করুন : আমি সদস্য_ সাইজের ম্যাক্রো জোকে এই কৌশলটি ব্যবহার করার পরামর্শ দিয়েছি বলে আমার মনে হয় আমি এটি ব্যবহার করব।


12
দ্বিতীয় ফর্মটি খুব সুন্দর (এবং ধারণাটি পরিষ্কার যে এটি নাল পয়েন্টার জড়িত না), তবে আপনার উল্লেখ করা উচিত যে প্রাক-সি 99 সংকলকগুলিতে এটি সম্ভব নয়।
আর .. গিটহাব বন্ধ করুন ICE

11

আপনি FIELD_SIZEOF(t, f)লিনাক্স কার্নেল ব্যবহার করতে পারেন নিখরচায় । এটি কেবল নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়েছে:

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

এই জাতীয় ম্যাক্রোর অন্যান্য উত্তরে উল্লেখ করা হয়েছে। তবে ইতিমধ্যে সংজ্ঞায়িত ম্যাক্রো ব্যবহার করা আরও পোর্টেবল।


4
লিনাক্স / কার্নেলের মধ্যে পাওয়া লিনাক্স কার্নেলগুলিতে ব্যবহৃত ম্যাক্রো হ'ল ফিল্ড_সিজোফ
কলিন ইয়ান কিং

@ কলিনআইঙ্কিং তাই স্ট্রাক্ট সদস্যের আকার পেতে সাধারণভাবে এটি একটি মূ ?় উপায়? এই জাতীয় ম্যাক্রো এখনও আধুনিক সিতে কোনও স্ট্যান্ডার্ডের অন্তর্ভুক্ত নয়?
সেন্ট অ্যান্টারিও

আমার জ্ঞানের মাপে স্ট্যান্ডার্ড সি তে কোনও সমান ম্যাক্রো নেই
কলিন ইয়ান কিং

সম্প্রতি হয়েছিল মুছে লিনাক্স / kernel.h থেকে।
অ্যান্ড্রি মাকুখা

10

একটি প্রিপ্রসেসর নির্দেশিকা ব্যবহার করুন, অর্থাত্ # নির্ধারণ:

#define TEXT_LEN 255

typedef struct _parent
{
  float calc ;
  char text[TEXT_LEN] ;
  int used ;
} parent_t ;

typedef struct _child
{
  char flag ;
  char text[TEXT_LEN] ;
  int used ;
} child_t ;

নায়ানের সাথে একমত। অন্যান্য সমাধানগুলি কাজ করে তবে ভিন্ন কিছু সম্পাদন করে না। আপনি যদি আরও সুস্পষ্ট হতে চান তবে এটিকে PARENT_TEXT_LEN বা সমান বর্ণনামূলক কিছু বলে। এরপরে আপনি বাফার দৈর্ঘ্যের ত্রুটিগুলি রোধ করতে আপনার কোড জুড়ে শর্তসাপেক্ষে এটি ব্যবহার করতে পারেন এবং এটি সহজ সংখ্যার তুলনা করে।
ডেভ মানকফ

1
আমি মনে করি আকারের সমাধানের সুবিধাটি হ'ল আপনার প্যারেন্ট স্ট্রাক্ট অ্যাক্সেসের দরকার নেই, যদি এটি কোনও লাইব্রেরিতে বা অন্য কোথাও সংজ্ঞায়িত করা হয়।

@ আইভিলকাউন: তবে আপনি কি: "লেখার পাঠ্য [সদস্য_সাকার (পিতামাতার, পাঠ্য)];" আপনাকে "পিতামাতাকে" উল্লেখ করতে হবে।
ডেভ ম্যানকফ

3
আমার মনে হয় না তুমি আমাকে বুঝতে পেরেছ ধরুন প্যারেন্ট স্ট্রাক্টটি drand48_data(stdlib.h এ সংজ্ঞায়িত) এবং আপনি আকারটি চান __x। আপনি #define X_LEN 3stdlib.h পরিবর্তন এবং পরিবর্তন করতে পারবেন না , member_sizeযখন প্যারেন্ট স্ট্রাস্টের উত্সটিতে আপনার অ্যাক্সেস না থাকে তখন ব্যবহার করা সর্বোত্তম, যা যুক্তিসঙ্গত পরিস্থিতির মতো বলে মনে হয়।

5

আপনি আকারের জন্য একটি প্রিপ্রসেসর নির্দেশিকা ব্যবহার করতে পারেন:

#define TEXT_MAX_SIZE 255

এবং এটি পিতামাতা এবং সন্তানের উভয় ক্ষেত্রেই ব্যবহার করুন।


হ্যাঁ, তবে এটি সর্বদা বিকল্প নয়: বলুন, লিনাক্সে /usr/include/bits/dirent.hক্ষেত্রের আকার d_name(স্ট্রাক্ট direct/ dirent) আর DIRSIZকোনও হার্ড-কোডেড হিসাবে সংজ্ঞায়িত করা হয়নি; তাই sizeof()নির্ভরতা রাখার শুধুমাত্র পরিষ্কার ভাবে মনে করা হয়
ジョージ

5

struct.h তাদের ইতিমধ্যে সংজ্ঞায়িত করা হয়েছে,

#define fldsiz(name, field) \
    (sizeof(((struct name *)0)->field))

সুতরাং আপনি পারে,

#include <stdlib.h> /* EXIT_SUCCESS */
#include <stdio.h>  /* printf */
#include <struct.h> /* fldsiz */

struct Penguin {
    char name[128];
    struct Penguin *child[16];
};
static const int name_size  = fldsiz(Penguin, name) / sizeof(char);
static const int child_size = fldsiz(Penguin, child) / sizeof(struct Penguin *);

int main(void) {
    printf("Penguin.name is %d chars and Penguin.child is %d Penguin *.\n",
           name_size, child_size);
    return EXIT_SUCCESS;
}

তবে, শিরোনামটি অনুসন্ধান করে দেখা যাচ্ছে যে এটি একটি BSD জিনিস এবং এএনএসআই বা পসিক্স মান নয়। আমি এটি একটি লিনাক্স মেশিনে চেষ্টা করেছি এবং এটি কার্যকর হয়নি; সীমিত উপযোগিতা।


4

আরেকটি সম্ভাবনা হ'ল কোনও ধরণের সংজ্ঞা দেওয়া। আপনি যে দুটি ক্ষেত্রের জন্য একই আকারটি নিশ্চিত করতে চান তা একটি সূচক যা আপনার কাছে তাদের জন্য একই শব্দার্থক রয়েছে, আমি মনে করি।

typedef char description[255];

এবং তারপরে একটি ক্ষেত্র আছে

description text;

আপনার উভয় প্রকারে।


4

সি ++ সমাধান:

আকারের (টাইপ :: সদস্য) পাশাপাশি কাজ করছে বলে মনে হচ্ছে:

struct Parent
{
    float calc;
    char text[255];
    int used;
};

struct Child
{
    char flag;
    char text[sizeof(Parent::text)];
    int used;
};

3
প্রশ্নটি সি ++ নয়, সি সম্পর্কে about
মার্ক

0

@ জো-অ্যাডামস, আপনাকে ধন্যবাদ! আমি একই জিনিসটি অনুসন্ধান করছিলাম, তবে চরের অরে জন্য নয় এবং এটি পুরোপুরি সূক্ষ্মভাবে এইভাবে কাজ করে:

#define member_dim(type, member) sizeof(((type*)0)->member) / \
                                 sizeof(((type*)0)->member[0])

struct parent {
        int array[20];
};

struct child {
        int array[member_dim(struct parent, array)];
};

int main ( void ) {
        return member_dim(struct child, array);
}

এটি প্রত্যাশিত হিসাবে 20 ফেরত দেয়।

এবং, @ ব্র্যান্ডন-হর্সলে, এটিও ভাল কাজ করে:

#define member_dim(type, member) sizeof(((type){0}).member) / \
                                 sizeof(((type){0}).member[0])
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.