আপনি কিভাবে সি তে স্ট্রাইকগুলির একটি অ্যারে তৈরি করবেন?


101

আমি স্ট্রকের একটি অ্যারে তৈরি করার চেষ্টা করছি যেখানে প্রতিটি স্ট্রাক্ট আকাশের দেহের প্রতিনিধিত্ব করে।

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

যারা এ পর্যন্ত পড়েছেন তাদের জন্য আরও তথ্য: গতিশীল হওয়ার জন্য আমার এগুলির কোনও প্রয়োজন নেই, আমি আগে থেকেই সমস্ত কিছুর আকার জানি / সংজ্ঞায়িত করি। আমি এটির একটি বৈশ্বিক অ্যারে হওয়ারও প্রয়োজন কারণ আমি এটি বিভিন্ন ধরণের সংজ্ঞায়িত যুক্তি (যেমন GLUT পদ্ধতি) দ্বারা অ্যাক্সেস করছি।

এইভাবে আমি আমার শিরোনামে স্ট্রাক্টটি সংজ্ঞায়িত করছি:

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

স্ট্রাক্টটির অভ্যন্তরটি সংজ্ঞায়নের আগে আমার কাছে অন্যান্য বৈশ্বিক পরিবর্তনশীলগুলির একটি তালিকা রয়েছে যা আমি সংজ্ঞায়িত করছি এবং এর মধ্যে একটি হ'ল এই কাঠামোর অ্যারে (মূলত, যদি আমি আমার ফোগড স্পিকের ক্ষেত্রে খুব অস্পষ্ট হয়ে থাকি তবে নীচের লাইনটি উপরের স্টাফের উপরে):

struct body bodies[n];

ঠিক তাই আপনি জানেন, nএমন কিছু যা আমি বৈধভাবে সংজ্ঞায়িত করেছি (যেমন #define n 1)।

আমি এই অ্যারেটিকে বিভিন্ন বিভিন্ন পদ্ধতিতে ব্যবহার করি তবে সবচেয়ে সহজ এবং কমপক্ষে স্থান গ্রহণ করা আমার মূলটির একটি সরলিকৃত রূপ is এখানে আমি প্রতিটি স্ট্রাক্টের সমস্ত ভেরিয়েবলের সূচনা করি, কিছু উপায়ে পরিবর্তন করার আগে কেবল নির্দিষ্টর জন্য ভেরিয়েবলগুলি সেট করতে:

  int a, b;
 for(a = 0; a < n; a++)
 {
        for(b = 0; b < 3; b++)
        {
            bodies[a].p[b] = 0;
            bodies[a].v[b] = 0;
            bodies[a].a[b] = 0;
        }
        bodies[a].mass = 0;
        bodies[a].radius = 1.0;
 }

বর্তমান ত্রুটিটি যেটির মুখোমুখি হচ্ছি তা হ'ল nbody.c:32:13: error: array type has incomplete element typeলাইন ৩২ যেখানে আমি স্ট্রাক্টগুলির অ্যারে তৈরি করছি।

একটি শেষ স্পষ্টতা, শিরোনাম দ্বারা আমি উপরের স্থানটি বলতে int main(void)চাই তবে একই *.cফাইলটিতে।


ঠিক আছে, এটা আমার জন্য ভাল কাজ করে। আপনি কি ঘোষণার struct body bodies[n];আগে struct body {}ঘোষণা দিচ্ছেন না?
জ্যাক

নোট করুন যে চলক-দৈর্ঘ্যের অ্যারেগুলি ব্যবহার করার সময় প্রায়শই রহস্যজনক বাগ বা ক্রাশ হতে পারে যখন অ্যারের আকার আপনার সিস্টেমে প্রোগ্রামের স্ট্যাকের আকার ছাড়িয়ে যায় (যা প্রোগ্রামার হিসাবে আপনার নিয়ন্ত্রণের বাইরে চলে যায়)। এই ধরণের জিনিসটির জন্য malloc () ব্যবহার করা ভাল।
এড্রিয়ান

@ অ্যাড্রিয়ান আমি মনে করি যেহেতু এটি একটি #defineডি মান, এটি পরিবর্তনশীল নয়। এটি ঠিক যেমনটি হবে struct body bodies[1], বা এর মান যা nহবে।
রেডউলফ প্রোগ্রাম

রেডউল্ফপ্রোগ্রাম আহ, দুঃখিত, আমি এটি বিবেচনা করি নি। রেকর্ডের জন্য, যদি nকোনও ধ্রুবক হয় যা সংকলনের সময় নির্ধারণ করা যেতে পারে আপনি সম্ভবত নিরাপদ।
এড্রিয়ান

উত্তর:


107
#include<stdio.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

struct body bodies[n];

int main()
{
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}

এই কাজ করে। আপনার প্রশ্নটি উপায় দ্বারা খুব পরিষ্কার ছিল না, সুতরাং উপরের সাথে আপনার উত্স কোডের বিন্যাসটি মিলিয়ে নিন।


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

4
হাই, .... 59 টি পছন্দ? আমি স্ট্রাক্টের অ্যারেগুলি দেখিনি, আমি কেবল আঘাত করা থেকে পরিবর্তনশীল অ্যারে দেখতে পাচ্ছি ...

12

আমি মনে করি আপনি এটিও সেভাবে লিখতে পারতেন। আমিও একজন ছাত্র তাই আপনার লড়াই বুঝতে পারছি। কিছুটা দেরি হয়ে গেলেও ঠিক আছে।

#include<stdio.h>
#define n 3

struct {
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}bodies[n];

12

সুতরাং ব্যবহার করে এগুলি একসাথে রাখার জন্য malloc():

int main(int argc, char** argv) {
    typedef struct{
        char* firstName;
        char* lastName;
        int day;
        int month;
        int year;

    }STUDENT;

    int numStudents=3;
    int x;
    STUDENT* students = malloc(numStudents * sizeof *students);
    for (x = 0; x < numStudents; x++){
        students[x].firstName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].firstName);
        students[x].lastName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].lastName);
        scanf("%d",&students[x].day);
        scanf("%d",&students[x].month);
        scanf("%d",&students[x].year);
    }

    for (x = 0; x < numStudents; x++)
        printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);

    return (EXIT_SUCCESS);
}

8
আপনার ম্যালোক লাইনে নামস্টুডেন্টস * সাইজ (স্টুডেন্ট) থাকা উচিত?
টড

@ টড এটি না করাই ভাল। sizeof *studentsএকই জিনিস এবং এটি যদি ভুল হয় না যদি শিক্ষার্থী কখনও পরিবর্তন হয়।
ট্রেন্টক্লাব

@ ট্রেন্টক্লিল {num স্টুডেন্টস} পরিমাণ পয়েন্টারের জন্য তিনি মেমরি বরাদ্দ করেছেন। কাঠামো নয়, পয়েন্টার। পয়েন্টারের আকারটি সাধারণত 4 বাইট হয়, ইতিমধ্যে কাঠামোর আকার 20 বাইট হয়। 20 বাইট 4 টি দ্বারা বিভাজ্য সংখ্যা, সুতরাং কোনও প্যাডিং প্রয়োজন হয় না এবং কাঠামো শুরু থেকে 20 তম বাইটে সংরক্ষণ করা হয়। এটি কেবলমাত্র কাজ করে কারণ আপনি কেবলমাত্র একটি বিশেষ ক্ষেত্রে মেমরি বরাদ্দ করেন। অন্যথায় অন্যান্য mallocs আপনার কাঠামোর স্মৃতি ওভাররাইট করতে পারে, কারণ এটি বরাদ্দ নেই এবং আপনি আপনার শিক্ষার্থীর স্মৃতিকে ওভারফ্লাউড করেছেন।
জন স্মিথ

4
@ জনস্মিত আপনি ভুল করেছেন; এটি আবার পড়ুন। sizeof *studentsযা বোঝানো হয়েছে তার আকার , অর্থাত্ sizeof(STUDENT)না sizeof(STUDENT*)। আপনি যে সঠিক ptr = malloc(num * sizeof *ptr)প্রতিবাদটি রক্ষা করার কথা বলেছিলেন সেই সঠিক ভুলটি আপনি করছেন । এটি এখানে দেখুন (সার্ভারটি নোট করুন, বেশিরভাগ আধুনিক পিসিগুলির মতোই, 8 বাইট পয়েন্টার রয়েছে যাতে আকারগুলি 4 এবং 20 এর পরিবর্তে 8 এবং 32 হয়)।
ট্রেন্টক্লা

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

8

সরানো

struct body bodies[n];

পরে

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

বাকি সব ঠিক আছে।


6

স্ট্রাক্টের অ্যারের আরম্ভ করার আরেকটি উপায় হ'ল অ্যারে সদস্যদের স্পষ্টভাবে আরম্ভ করা। যদি অনেক বেশি স্ট্রাক্ট এবং অ্যারে সদস্য না থাকে তবে এই পদ্ধতিটি কার্যকর এবং সহজ।

ব্যবহার করুন typedefপুনরায় ব্যবহার করা থেকে বিরত সুনির্দিষ্টভাবে উল্লেখ করা structবিবৃতি সব আপনি একটি struct ভেরিয়েবল ডিক্লেয়ার:

typedef struct
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}Body;

তারপরে আপনার স্ট্রাক্টের অ্যারে ঘোষণা করুন। প্রতিটি উপাদানটির সূচনা ঘোষণার সাথে চলে:

Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};

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


4
এটা খুবই পছন্দ করি! সুন্দর এবং সহজ উত্তর 👍
এথান

1

এই ত্রুটির অর্থ হ'ল সংকলক আপনার স্ট্রাক্টের ধরণের সংজ্ঞাটি স্ট্রাক্টসগুলির অ্যারের ঘোষণার আগে খুঁজে পেতে সক্ষম হয় না, যেহেতু আপনি বলছেন যে আপনি একটি শিরোনাম ফাইলটিতে কাঠামোর সংজ্ঞা রেখেছেন এবং ত্রুটিটি nbody.cতখন রয়েছে আপনি সঠিকভাবে হেডার ফাইলটি অন্তর্ভুক্ত করছেন কিনা তা পরীক্ষা করা উচিত। আপনার পরীক্ষা করুন #includeএবং নিশ্চিত করুন যে কাঠামোর সংজ্ঞাটি সেই ধরণের কোনও ভেরিয়েবল ঘোষণার আগে সম্পন্ন হয়েছে।


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

@ নিমগুলি সঠিক, শিরোনাম দ্বারা আমি mainবিবৃতিটির উপরের অঞ্চলটি বোঝাই ।
আমনদীপ

1

পয়েন্টার ব্যবহার করে সমাধান:

#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double *mass;
};


int main()
{
    struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.