• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Tworzenie struktury, a w niej adres do następnej struktury.

Object Storage Arubacloud
0 głosów
143 wizyt
pytanie zadane 26 listopada 2016 w C i C++ przez Caishen Nowicjusz (210 p.)

Cześć. Potrzebuję stworzyć strukturę, w której jedną z danych będzie adres do następnej struktury tego samego typu. 

typedef struct {
        float x,y,z;
        char nazwa[DL];
        struct PtList *NextList;//wskaznik na nastepna strukture;
    }PtList;

 

 

No i tworze jakąś strukturę 
PtList *cos i PtList *dwa;

I jej adres chciałbym przesłać do 

cos.NextList=dwa; ale to nie działa. 

Jak powinienem to ugryźć?

1 odpowiedź

0 głosów
odpowiedź 26 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 27 listopada 2016 przez plkpiotr

No i tworze jakąś strukturę  
PtList *cos i PtList *dwa

Tworzysz nie reprezentację struktury, ale wskaźniki na strukturę ;)

komentarz 26 listopada 2016 przez Caishen Nowicjusz (210 p.)

Może pokażę Ci cały kod. Bo to są dla mnie początku i nie do końca rozumiem zachowania struktur i wskaźników. 

 

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

#define DL 36

//deklaracja struktury
typedef struct {
        float x,y,z;
        char nazwa[DL];
        struct PtList *NextList;//wskaznik na nastepna liste;
    }PtList;


//wczytywanie lini do struktury
PtList *load(void){
    PtList *wsk=malloc(sizeof (PtList));
    if(wsk==NULL) exit(0);

    float a,b,c;

    scanf("%f%f%f",&a,&b,&c);
    wsk->x=a;
    wsk->y=b;
    wsk->z=c;
    fgets(wsk->nazwa,DL,stdin);

    return wsk;
}

int main()
{
    PtList *poczatek=load();
    PtList *poprzedni=poczatek;
    PtList *nastepny;

    char Koniec[]="KONIEC";
    int IlePkt=0;

    while(strcmp(poprzedni->nazwa,Koniec) && !feof(stdin)){
        IlePkt++;
        nastepny=load();
        poprzedni.NextList=nastepny;
        printf("%.f %.2f %.2f %s",(*nastepny).x, nastepny->y, nastepny->z, nastepny->nazwa);
    }
    return 0;
}

 

 

Chciałbym mieć w poprzedniej strukturze wskaźnik do następnej. 

komentarz 26 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 27 listopada 2016 przez plkpiotr
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DL 36

//deklaracja struktury
struct PtList {
    float x, y, z;
    char nazwa[DL];
    struct PtList* NextList;//wskaznik na nastepna liste;
};

//wczytywanie lini do struktury
PtList* load(void) {
    PtList* wsk = (PtList*)malloc(sizeof(PtList));
    if (wsk == NULL) exit(0);
    float a, b, c;
    scanf("%f%f%f", &a, &b, &c);
    wsk->x = a;
    wsk->y = b;
    wsk->z = c;
    fgets(wsk->nazwa, DL, stdin);
    return wsk;
}

int main() {
    PtList *poczatek = load();
    PtList *poprzedni = poczatek;
    PtList *nastepny;
    char Koniec[] = "KONIEC";
    int IlePkt = 0;
    while (strcmp(poprzedni->nazwa, Koniec) && !feof(stdin)) {
        IlePkt++;
        nastepny = load();
        (*poprzedni).NextList = (*nastepny).NextList;
        printf("%.f %.2f %.2f %s", (*nastepny).x, nastepny->y, nastepny->z, nastepny->nazwa);
    }
    return 0;
}

Nie analizowałem dokładnie na czym polega działanie funkcji load, więc daj znać czy program działa zgodnie z Twoimi oczekiwaniami ;)

W 8 linijce usunąłem słowo typedef, jakoś bardziej naturalne wydawało mi się takie podejście, choć Twoje oczywiście nie jest błędem.

W 16 linijce potrzebujemy dynamicznie zaalokować pamięć właśnie na PtList, u Ciebie nie ma informacji przed malloc, stąd próbowaliśmy domyślnie alokować na void.

Kluczowe - linia 36 - aby dostać się do wartości wskaźników *poprzedni oraz *nastepny (bo w domyśle przechowują adres pod którym kryją się wartości) to musimy użyć operatora wyłuskiwania *. W ten sposób zamiast operować na adresie tychże wskaźników to, operujemy na tym co się pod nim kryje. A kryje się pole struktury (będące notabene też wskaźnikiem) i to im chcemy przypisać odpowiednie dane. :)

Poprawna wersja w niżej.

komentarz 27 listopada 2016 przez Caishen Nowicjusz (210 p.)

Kluczowe - linia 36 - aby dostać się do wartości wskaźników *poprzedni oraz *nastepny (bo w domyśle przechowują adres pod którym kryją się wartości) to musimy użyć operatora wyłuskiwania *. W ten sposób zamiast operować na adresie tychże wskaźników to, operujemy na tym co się pod nim kryje. A kryje się pole struktury (będące notabene też wskaźnikiem) i to im chcemy przypisać odpowiednie dane. :)

Tylko dla linii 36:
 

        (*poprzedni).NextList = (*nastepny).NextList;

Do (*nastepny).NextList jeszcze nic nie jest przepisane.   Do (*poprzedni).NextList chciałbym przypisać wskaźnik do struktury. Tak, żebym mógł wypisywać strukturę za strukturą. 

komentarz 27 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Przepraszam, zrozumiałem to w inny sposób, mój błąd. Zatem chcesz, aby wskaźnik w strukturze wskazywał na inny (następny) element struktury? To spróbuj coś takiego: 

(*poprzedni).NextList = nastepny;

Budowa Twojego programu przypomina listę jednokierunkową, pod właśnie takim pojęciem w wyszukiwarce/książkach znajdziesz algorytmy do dodawania, wyświetlania, czy usuwania elementów w takiej strukturze danych.

komentarz 27 listopada 2016 przez Caishen Nowicjusz (210 p.)

strukturze wskazywał na inny (następny) element struktury?

Nie wiem czy do końca się rozumiemy więc spróbuję to sparafrazować. 
Mam w strukturze zapisaną książkę (tytuł, autor, rok). 
W każdej strukturze zawierającej książkę chciałbym jeszcze mieć adres do następnej książki. 

 

komentarz 27 listopada 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Tak jak wyżej powinno zadziałać, jeżeli nie to się poddaje ;)
komentarz 27 listopada 2016 przez Caishen Nowicjusz (210 p.)

nie bangla ;( 
W 58 lini się wywala:
 

error: assignment from incompatible pointer type [-Werror]|

https://dpaste.de/Xx1Q

 

 

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

#define DL 36

//deklaracja struktury
typedef struct {
        float x,y,z;
        char nazwa[DL];
        struct PtList *NextList;//wskaznik na nastepna liste;
    }PtList;


//wczytywanie lini do struktury
PtList *load(void){
    PtList *wsk=(PtList*)malloc(sizeof (PtList));
    if(wsk==NULL) exit(0);

    float a,b,c;

    scanf("%f%f%f",&a,&b,&c);
    wsk->x=a;
    wsk->y=b;
    wsk->z=c;
    fgets(wsk->nazwa,DL,stdin);

    return wsk;
}

void write(PtList *wsk){
    printf("%.f %.2f %.2f %s",(*wsk).x, wsk->y, wsk->z, wsk->nazwa);
}

int main()
{
    PtList *poczatek=load();
    PtList *poprzedni=poczatek;
    PtList *nastepny;

    char Koniec[]="  KONIEC";
    Koniec[6]='\n';
    Koniec[7]='\0';
    int IlePkt=0;

    printf("test\n");


    while(strcmp(poprzedni->nazwa,Koniec) && !feof(stdin)){
        nastepny=load();
        IlePkt++;

        if(strncmp(nastepny->nazwa,Koniec,6)){
            printf("POZYTYWNIE\n");
        }else printf("NEGATYWNIE\n");


        poprzedni->NextList=nastepny;
        write(nastepny);
    }

    nastepny->NextList=NULL;
    return 0;
}

 

Podobne pytania

0 głosów
1 odpowiedź 275 wizyt
0 głosów
2 odpowiedzi 138 wizyt
0 głosów
1 odpowiedź 106 wizyt
pytanie zadane 30 grudnia 2017 w C i C++ przez Jarvis Nowicjusz (170 p.)

92,619 zapytań

141,468 odpowiedzi

319,786 komentarzy

62,001 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...