आप C में किस प्रकार की संरचना बनाते हैं?


100

मैं एक ऐसी संरचना बनाने की कोशिश कर रहा हूँ जहाँ प्रत्येक संरचना एक खगोलीय पिंड का प्रतिनिधित्व करती है।

मेरे पास स्ट्रक्चर्स के साथ उतना अनुभव नहीं है, यही कारण है कि मैंने सरणियों के एक पूरे समूह के बजाय उनका उपयोग करने का प्रयास करने का निर्णय लिया। हालाँकि, मैं कई अलग-अलग त्रुटियों में भागता रहता हूँ। मैंने उन तकनीकों को लागू करने की कोशिश की है, जो मैंने विभिन्न थ्रेड्स और स्टैकऑवरफ़्लो पर देखी हैं (जैसे कि सी और सी में स्ट्रक्चर्स का एरे - स्ट्रक्चर्स का एरेलाइज़ सरणी ), हालाँकि ये सभी लागू नहीं थे।

उन लोगों के लिए आगे की जानकारी जिन्होंने इसे पढ़ा है: मुझे गतिशील होने के लिए किसी की आवश्यकता नहीं है, मैं पहले से ही सब कुछ के आकार को जानता / परिभाषित करता हूं। मुझे एक वैश्विक सरणी के रूप में भी इसकी आवश्यकता है क्योंकि मैं इसे कई अलग-अलग तरीकों से एक्सेस कर रहा हूं, जिन्होंने तर्कों को परिभाषित किया है (यानी 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)।

मैं इस सरणी को कई अलग-अलग तरीकों से उपयोग करता हूं, लेकिन सबसे आसान और कम से कम एक स्थान का उपभोग करना मेरे मुख्य का एक सरल रूप है। यहाँ मैं प्रत्येक चर में सभी चर को आरंभीकृत करता हूं, बस चर को कुछ में बदलने से पहले निश्चित करने के लिए:

  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जहां लाइन 32 वह जगह है जहां मैं स्ट्रक्चर्स की सरणी बना रहा हूं।

एक अंतिम स्पष्टीकरण, हेडर से मेरा मतलब है ऊपर की जगह int main(void)लेकिन उसी *.cफ़ाइल में।


खैर, यह मेरे लिए ठीक काम करता है। क्या आप घोषणा करने struct body bodies[n];से पहले struct body {}घोषणा नहीं कर रहे हैं ?
जैक

ध्यान दें कि चर-लंबाई सरणियों का उपयोग करना अक्सर रहस्यमय कीड़े या क्रैश का कारण बन सकता है जब सरणी का आकार आपके सिस्टम पर प्रोग्राम के स्टैक आकार से अधिक हो जाता है (जो प्रोग्रामर के रूप में आपके नियंत्रण से पूरी तरह से बाहर है)। इस तरह की चीज के लिए मॉलोक () का उपयोग करना बेहतर है।
एड्रियन

जवाबों:


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

यह ठीक काम करता है। आपका प्रश्न इस तरह से बहुत स्पष्ट नहीं था, इसलिए उपरोक्त के साथ अपने स्रोत कोड के लेआउट का मिलान करें।


इसके अलावा, मेरे पास संरचना प्रकार की घोषणा के बीच प्लेसमेंट के बारे में एक प्रश्न है और फिर वास्तव में इसका एक उदाहरण है - मेरे पास एक अलग संरचना है, एक जिसे मैंने नीचे की सामग्री को परिभाषित किया है जहां मैं पहली बार इसका उदाहरण बनाता हूं (सिर्फ एक इस बार, सरणी नहीं), इसलिए यह त्रुटियों की विशाल श्रृंखला क्यों नहीं बनी? यह ठीक काम किया, जिसने मुझे यह सोचने के लिए प्रेरित किया कि एक सरणी बनाने के मेरे प्रयास को भी काम करना चाहिए था, लेकिन इस बार यह काम नहीं किया। इसके अलावा, आपके उत्तर के लिए धन्यवाद, यह काम किया।
अमनदीप

1
हाय, .... 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];

11

तो यह सब एक साथ उपयोग करने के लिए 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एक ही बात है और यह गलत नहीं होगा अगर छात्र कभी बदलाव के लिए होता है।
१।

@trentcl उन्होंने संकेत के {{StStudents} राशि के लिए मेमोरी आवंटित की है। संरचनाएं नहीं, बल्कि संकेत हैं। सूचक आकार सबसे अधिक 4 बाइट्स है, इस बीच संरचना का आकार 20 बाइट्स है। 20 बाइट्स संख्या 4 से विभाज्य है, इसलिए किसी भी पैडिंग की जरूरत नहीं है और संरचना हर 20 वें बाइट पर शुरू पते से संग्रहीत होती है। यह केवल इसलिए काम करता है क्योंकि आप केवल एक विशेष मामले के लिए मेमोरी आवंटित करते हैं। अन्यथा अन्य मैलोडो आपकी संरचनाओं की मेमोरी को ओवरराइट कर सकता है, क्योंकि इसका आवंटन नहीं किया गया है और आपने अपनी छात्र मेमोरी को ओवरफ्लो कर दिया है।
जॉन स्मिथ

3
@ जॉनसन आप गलत हैं; इसे फिर से पढ़ो। क्या कहाsizeof *students जाता है पर आकार का आकार , यानी , नहीं है । आप सटीक गलती कर रहे हैं कि मुहावरे के खिलाफ गार्ड होना चाहिए। इसे यहां जांचें (अधिकांश आधुनिक पीसी की तरह सर्वर पर ध्यान दें, 8 बाइट पॉइंटर्स हैं इसलिए आकार 4 और 20 के बजाय 8 और 32 हैं)। sizeof(STUDENT)sizeof(STUDENT*)ptr = malloc(num * sizeof *ptr)
ट्रेंटक्ल

@trentcl स्पष्टीकरण के लिए धन्यवाद। मैं इसे स्वयं के आरंभीकरण में dereferencing पॉइंटर के सिंटैक्स द्वारा भ्रमित हो गया। मैं कहूंगा कि यह थोड़ा भ्रमित करने वाला है, लेकिन निश्चित रूप से अधिक कॉम्पैक्ट समाधान है।
जॉन स्मिथ

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कथन का फिर से उपयोग करने से बचने के लिए विशेष का उपयोग करें :

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

दोहराने के लिए, यह एक सरल और सीधा समाधान है यदि आपके पास बहुत सारे सरणी तत्व और बड़े संरचना सदस्य नहीं हैं और यदि आप, जैसा कि आपने कहा है, अधिक गतिशील दृष्टिकोण में रुचि नहीं रखते हैं। यह दृष्टिकोण उपयोगी भी हो सकता है यदि संरचना सदस्यों को नामांकित-चर (और न केवल ऊपर दिए गए उदाहरण की तरह संख्याओं) के साथ आरम्भ किया जाता है, जिससे यह कोड-रीडर को एक संरचना और उसके सदस्यों के उद्देश्य और कार्य का बेहतर अवलोकन देता है अनुप्रयोग।


1
इसे प्रेम करें! अच्छा और सरल जवाब and
एथन

1

उस त्रुटि का मतलब है कि कंपाइलर, संरचना के सरणी की घोषणा से पहले आपकी संरचना के प्रकार की परिभाषा खोजने में सक्षम नहीं है, क्योंकि आप कह रहे हैं कि आपके पास हेडर फ़ाइल में संरचना की परिभाषा है और त्रुटि nbody.cतब है आपको यह देखना चाहिए कि क्या आप हेडर फ़ाइल को सही तरीके से शामिल कर रहे हैं। अपने प्रकार #includeकी जाँच करें और सुनिश्चित करें कि संरचना की परिभाषा उस प्रकार के किसी भी चर को घोषित करने से पहले की गई है।


मुझे संदेह है कि ओपी का मतलब हेडर फ़ाइल के रूप में हेडर है, जैसा कि उन्होंने लिखा है, "नीचे की लाइन सामान के ऊपर है" संरचना सरणी घोषणा से पहले जो उनकी nbody.c फ़ाइल में है। उसे जगाने के लिए इंतजार करें और संदेह को दूर करें।
एन आई एम एस

@nims सही है, हेडर से मेरा मतलब है कि 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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.