जैसा कि आप मेरे कोड में देख सकते हैं, मैं उपयोगकर्ता से कुछ मान (रक्षात्मक प्रोग्रामिंग के साथ) इनपुट करने के लिए कहता हूं और फिर मैं इन मानों को सही क्रम में सूची में रखना चाहता हूं। यदि उपयोगकर्ता के मान 5,4,3 थे, तो सूची [5, 4, 3] होनी चाहिए। हालांकि यह काम नहीं करता... शायद कुछ मदद?

मैंने सूची शीर्ष के लिए और अंतिम तत्व last को इंगित करने वाले सूचक के लिए डबल पॉइंटर (रेफरी द्वारा कॉल करने के लिए) का उपयोग किया। क्या यह सही है?

मेरा कंपाइलर कहता है कि यह insert फ़ंक्शन (*last->next = temp;) में एक त्रुटि है। विशेष रूप से यह कहता है request from member 'next' in something not a structure or union

#include <stdio.h>
#include <stdlib.h>

struct node {
    int data;
    struct node *next;
};

typedef struct node *Nodeptr;
typedef struct node Node;

void insert(Nodeptr *list, Nodeptr *last, int info) {
    Nodeptr temp;
    temp = (Nodeptr)malloc(sizeof(Node));
    temp->data = info;

    if (!(*list)) {
        temp->next = NULL;
        *list = temp;
        *last = temp; // points to last node
    } else {
        *last->next = temp; //points to last node
        *last = temp;
        *last->next = NULL;
    }
}

void print(Nodeptr list) {
    Nodeptr aux;
    aux = list;

    if (!list) {
        puts("Empty!\n");
    } else {
        while (aux != NULL) {
            printf("%d ", aux->data);
            aux = aux->next;
        }
    }
}

main() {
    Nodeptr head = NULL;
    Nodeptr last;
    int i, num;

    for (i = 0; i < 3; i++) {
        do {
            printf("Give number: ");
            scanf("%d", &num);

            if (num < 10 || num > 99) {
                printf("\nWrong!.");
            }
        } while (!(num >= 10 && num <= 99)); 

        insert(&head, &last, num);
    }

    print(head);

    getch();
}
1
Navy Alsk 1 मार्च 2020, 19:12
typedef struct node *Nodeptr; टाइपडीफ पॉइंटर्स को आमतौर पर खराब स्टाइल माना जाता है। साथ ही Node* वैसे भी Nodeptr से थोड़ा छोटा है।
 – 
KamilCuk
3 मार्च 2020, 00:33

2 जवाब

हां, इस स्थिति में डबल पॉइंटर्स का उपयोग करना सार्थक है।

हालांकि, ऑपरेटर वरीयता के नियमों के अनुसार, -> * ऑपरेटर की तुलना में ऑपरेटर की प्राथमिकता अधिक होती है। इसलिए, आपको इस तरह कोष्ठक जोड़ना होगा:

(*last)->next=temp;

1
Andreas Wenzel 1 मार्च 2020, 20:06

डबल पॉइंटर्स के साथ आपका दृष्टिकोण ठीक है, लेकिन टाइपपीफ के पीछे पॉइंटर्स को छुपाना अक्सर भ्रमित और त्रुटि प्रवण माना जाता है। आपको शायद इससे बचना चाहिए और केवल void insert(Node **list, Node **last, int info), आदि लिखना चाहिए।

*last->next = temp; पर त्रुटि ऑपरेटर वरीयता नियमों के कारण है: पोस्टफ़िक्स ऑपरेटर जैसे -> उपसर्ग ऑपरेटरों की तुलना में अधिक मजबूत होते हैं, इसलिए कथन को *(last->next) = temp; के रूप में पार्स किया जाता है। इसके बजाय आपको (*last)->next = temp; लिखना चाहिए।

रक्षात्मक प्रोग्रामिंग के संबंध में, यह निश्चित रूप से एक अच्छा तरीका है। मेरा सुझाव है कि आप और भी आगे बढ़ें और:

  • अमान्य इनपुट का पता लगाने के लिए scanf() के रिटर्न वैल्यू की जांच करें और इसे एक साधारण लूप के साथ छोड़ दें।
  • स्मृति आवंटन विफलताओं की जाँच करें
  • main के लिए उचित प्रोटोटाइप का उपयोग करें और 0 लौटाएं।
  • आवंटित स्मृति मुक्त करें

यहाँ एक संशोधित संस्करण है:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node Node;
struct Node {
    int data;
    Node *next;
};

void insert(Node **head, Node **tail, int info) {
    Node *temp;
    temp = malloc(sizeof(*temp));
    if (temp == NULL) {
        fprintf(stderr, "cannot allocate Node\n");
        exit(1);
    }
    temp->data = info;
    temp->next = NULL;

    if (!*head) {
        *head = temp;
    } else {
        (*tail)->next = temp;
    }
    *tail = temp;
}

void print(const Node *list) {
    const Node *aux = list;

    if (!list) {
        printf("Empty!\n");
    } else {
        while (aux != NULL) {
            printf("%d ", aux->data);
            aux = aux->next;
        }
        printf("\n");
    }
}

void freelist(Node **list) {
    while (*list) {
        Node *aux = *list;
        *list = aux->next;
        free(aux);
    }
}

int main(void) {
    Node *head = NULL;
    Node *last = NULL;
    int i, c, num, res;

    for (i = 0; i < 3;) {
        printf("Give number: ");
        res = scanf("%d", &num);
        if (res == EOF)
            break;
        if (res == 1) {
            if (num < 10 || num > 99) {
                printf("Invalid value: must be >= 10 and <= 99\n");
            } else {
                insert(&head, &last, num);
                i++;
            }
        } else {
            printf("Invalid input\n");
            while ((c = getchar()) != EOF && c != '\n')
                continue;
            if (c == EOF)
                break;
        }
    }
    print(head);
    freelist(head);
    getch();
}
0
chqrlie 3 मार्च 2020, 00:51