Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Wskaźnik na strukturę jak uzyskać

Marek_Gorecki 24 Gru 2017 23:25 798 29
  • #1 24 Gru 2017 23:25
    Marek_Gorecki
    Poziom 16  

    Witam,

    jeżeli mam taka strukturę:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    To w jaki sposób uzyskać wskaźnik na tą strukturę.
    Próbowałem tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    a także próbowałem tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    zarówno piersza wersja, jak i druga nie działa - to znaczy kompilator zgłasza błedy.

    0 29
  • Pomocny post
    #2 24 Gru 2017 23:47
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Chcesz wskaźnik na strukturę, deklarujesz wskaźnik na "char", wiec czemu dziwisz się kompilatorowi że zgłasza błąd?

    struct mystruct* wsk = &czas;

    Warto popracować nad podstawami wskaźników w języku C, bo braki wyjdą przy pierwszej nadarzającej się okazji.

    0
  • #3 25 Gru 2017 01:12
    2675900
    Użytkownik usunął konto  
  • #4 25 Gru 2017 01:45
    JacekCz
    Poziom 35  

    Marek_Gorecki napisał:

    zarówno piersza wersja, jak i druga nie działa - to znaczy kompilator zgłasza błedy.


    Jeśli zajmowałeś sie programowaniem, to wiesz, że komunikaty o błędach mają swoją treść, i się je cytuje na portalach pomocowych.
    Choć komuś kumatemu ich przeczytanie podpowiada rozwiązanie, miałbyś wynik od ręki, a nie po godzinach.

    Moderowany przez tmf:

    część posta zawierającą uwagi personalne skasowałem.

    0
  • #5 25 Gru 2017 13:15
    Marek_Gorecki
    Poziom 16  

    Dzięki działa.

    Więc teraz mam wskaźnik
    struct mystruct* wsk = &czas;

    A teraz chciałbym mieć dostęp do tej struktury , do każdego bajtu z osobna, tak abym mógł ją wypełnić w pętli (wszystkie pola są typu char).
    Czyli chciałbym zadeklarować teraz wskaźniktypu char, który wskazywałby na poczatek tej struktury, czyli coś takiego:

    char * ptr=(char *) wsk;

    Ale tu też kompilator zgłasza bład typu"const expression expected" .
    Co robie źle?

    0
  • #6 25 Gru 2017 13:47
    tmf
    Moderator Mikrokontrolery Projektowanie

    @Marek_Gorecki To zdefiniuj sobie tą strukturę w ramach unii, w której kolejne pole to bedzie tablica char. W ten sposób będziesz mógł uzyskać dostęp do charowych reprezentacji pól. Oczywiście można też zastosować rzutowanie. Pamiętaj tylko, że często to co chcesz zrobić nie jest najlepszym pomysłem.

    0
  • #7 25 Gru 2017 13:53
    2675900
    Użytkownik usunął konto  
  • #8 25 Gru 2017 14:03
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Przecież ta struktura ma 3 pola, daj sobie spokój z "optymalizacją" polegającą na wypełnianiu jej w pętli, tylko zrób to normalnie. Jak będziesz takie cuda wymyślał, to 3x dziennie będziesz pytał o coś i nie skończysz przez miesiąc.

    0
  • #9 25 Gru 2017 14:18
    Marek_Gorecki
    Poziom 16  

    Piotrus_999 napisał:
    W zależności od stopnia poprawnosci:

    1. Najbardziej poprawne:
    Czytasz dane do tablicy
    robisz memcpy z tablicy do struktury



    A podpowiesz mi kolego, jak skopiować strukturę do tablicy i z tablicy do struktury?

    Jeżeli mam taką strukturę:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    I teraz zadeklaruję tablicę
    Kod: c
    Zaloguj się, aby zobaczyć kod


    To czy prawidłowo będzie to tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Dodano po 1 [minuty]:

    Freddie Chopin napisał:
    Przecież ta struktura ma 3 pola, daj sobie spokój z "optymalizacją" polegającą na wypełnianiu jej w pętli, tylko zrób to normalnie. Jak będziesz takie cuda wymyślał, to 3x dziennie będziesz pytał o coś i nie skończysz przez miesiąc.


    Pytam edukacyjnie. A ta struktura ma tylko 3 pola tutaj. W rzeczywistości będzie ona zawierać całą listę dat i czasów, więc będzie duża.

    1
  • #10 25 Gru 2017 14:21
    2675900
    Użytkownik usunął konto  
  • #11 25 Gru 2017 14:24
    Marek_Gorecki
    Poziom 16  

    Piotrus_999 napisał:
    Marek_Gorecki napisał:
    To czy prawidłowo będzie to tak:
    memcpy(dane, czas, struct mystruct);
    Wybacz =- przeczytaj najpierw o języku C. Myślałem że miałeś chwilę słabości ale niestety nie znasz C w ogóle. Dopóki tego nie poprawisz dalsza moc jest bezcelowa


    Poprawiłem ten zapis, ale zbyt poźno na taki:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #12 25 Gru 2017 14:37
    2675900
    Użytkownik usunął konto  
  • #13 25 Gru 2017 15:38
    JacekCz
    Poziom 35  

    Piotrus_999 napisał:
    Wybacz =- przeczytaj najpierw o języku C. Myślałem że miałeś chwilę słabości ale niestety nie znasz C w ogóle. Dopóki tego nie poprawisz dalsza moc jest bezcelowa


    Też przez chwilę myślałem, ze kol. tylko "zdarzył się problem", zmieniłem myślenie na "nie czytał nic"

    Freddie Chopin napisał:
    Przecież ta struktura ma 3 pola, daj sobie spokój z "optymalizacją" polegającą na wypełnianiu jej w pętli, tylko zrób to normalnie. Jak będziesz takie cuda wymyślał, to 3x dziennie będziesz pytał o coś i nie skończysz przez miesiąc.


    Freddie Chopin napisał:
    Przecież ta struktura ma 3 pola, daj sobie spokój z "optymalizacją" polegającą na wypełnianiu jej w pętli, tylko zrób to normalnie. Jak będziesz takie cuda wymyślał, to 3x dziennie będziesz pytał o coś i nie skończysz przez miesiąc.


    wątek tylko do zamknięcia, a przeczytanie pierwszych 10 kartek książki rozwiązuje wszystkie problemy.
    Dodano po 48 [sekundy]:
    Marek_Gorecki napisał:

    A teraz chciałbym mieć dostęp do tej struktury , do każdego bajtu z osobna, tak abym mógł ją wypełnić w pętli (wszystkie pola są typu char).


    Najpierw zacznij normalnie używać języka, potem przyjdzie czas na hackerskie techniki.

    W strefie angielskiego mówi się "XY problem", czyli jakaś koncepcja jest niewłaściwa, jednak ją realizujemy, i stąd coraz dziwniejsze pytania. Zapytam ostatni raz: jaki rzeczywisty problem rozwiązujesz?

    Już pominę, czy masz mocne przekonanie, że 'char' to zawsze dokładnie 'bajt'. Możesz się zdziwić, ale to jeszcze nie teraz.

    0
  • #14 25 Gru 2017 17:28
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Marek_Gorecki napisał:
    Pytam edukacyjnie. A ta struktura ma tylko 3 pola tutaj. W rzeczywistości będzie ona zawierać całą listę dat i czasów, więc będzie duża.

    Edukacyjnie więc - do wypełniania w pętli służy tablica, a nie rzutowane struktury czy jakieś unie (wspomniane tutaj pomysły z uniami i type-punning są w standardzie języka opisane jako "undefined behaviour", zabronione jest odczytywanie pola "x" w unii jeśli zapisane zostało pole "y"). Jak struktura będzie miała 345 pól to tym bardziej bezsensownym pomysłem będzie wypełnianie jej w pętli, w sam raz świetna okazja żeby się gdzieś coś pomieszało.

    Kopiowanie przez memcpy() jeszcze jest akceptowalne, ale pod warunkiem, że kopiujesz jeden obiekt do drugiego, a nie że "wiem że wszystkie pola są typu char, to sobie zrobię rzutowanie". Bo w takim wypadku to zrób sobie tablicę i obok trzymaj definicje z opisowymi indeksami.

    Code:
    char data[3];
    
    #define GODZINA_INDEX 0
    #define MINUTA_INDEX 1
    #define MINUTA_INDEX 2

    data[GODZINA_INDEX] = 20;
    data[MINUTA_INDEX] = 10;
    data[MINUTA_INDEX] = 30;


    Problem solved.

    Jeśli uważasz że pętla jest lepsza, to przypuszczalnie zdziwi Cię informacja, że na wysokich poziomach optymalizacji kompilator "rozwija" krótkie pętle (zarówno "krótkie" pod względem ilości iteracji jak i ilości kodu), bo liniowy zestaw instrukcji jest szybszy niż ciągłe skoki i bawienie się licznikami.

    0
  • #15 25 Gru 2017 17:35
    Marek_Gorecki
    Poziom 16  

    Napisalem ten post w dziale „poczatkujacy”, myslalem ze cos sie dowiem. Ale wiekszosc odpowiedzi jest typu „Ja wiem , ale nie powiem.”
    Zapytam raz jeszcze , jak uzyskac wskaznik typu char na strykture.

    1
  • #16 25 Gru 2017 17:55
    JacekCz
    Poziom 35  

    Marek_Gorecki napisał:
    Napisalem ten post w dziale „poczatkujacy”, myslalem ze cos sie dowiem. Ale wiekszosc odpowiedzi jest typu „Ja wiem , ale nie powiem.”
    Zapytam raz jeszcze , jak uzyskac wskaznik typu char na strykture.


    Wiem i powiem: przeczytaj jakąkolwiek książkę nt C. Nawet gdybyś tylko przewertował kartki, zostało by Ci w pamięci wzrokowej tyle, aby rozwiązać zagadkę.
    Wszystko zostało przez kolegów powiedziane. Dostałeś przygotowaną wędkę z robakiem na końcu, zarzuconą do stawu, nawet nie masz ochoty jej szarpnąć.


    EDIT: używasz wszystkich potrzebnych Ci elementów we własnym kodzie (kodzie, który by teoretycznie uchodził za Twój własny). To jest żywy przykład, że wymuszając odpowiedzi sam sobie robisz krzywdę. Obejrzyj dokładnie wszystkie "robaczki" użyte we "własnym" kodzie, tam jest odpowiedź.


    Regulamin
    3.1.17.
    3.1.16.

    0
  • #17 25 Gru 2017 17:57
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Marek_Gorecki napisał:
    Zapytam raz jeszcze , jak uzyskac wskaznik typu char na strykture.

    My też spytamy raz jeszcze - po co chciałbyś uzyskać wskaźnik nieprawidłowego typu, skoro widać że gubisz się na najprostszych kwestiach języka?

    0
  • #18 25 Gru 2017 18:42
    Marek_Gorecki
    Poziom 16  

    Freddie Chopin napisał:
    Marek_Gorecki napisał:
    Zapytam raz jeszcze , jak uzyskac wskaznik typu char na strykture.

    My też spytamy raz jeszcze - po co chciałbyś uzyskać wskaźnik nieprawidłowego typu, skoro widać że gubisz się na najprostszych kwestiach języka?


    Ponieważ, chciałbym zrobić sobie strukturę z wszystkimi nastawami programu.
    Program ten jest do sterowania akwarium.
    Programowane są godziny włączeń i wyłączeń różnych doświetleń ( różna kolorystyka), a ponieważ są 4 kolory, więc par czasowych włącz - wyłacz jest wiele. Jeśli do tego dołożę, że mają być też dni, aby niepotrzebnie bajery te były właczane w godzinach pracy, to robi się tego naprawdę dużo.
    I teraz chodzi mi o to, aby stworzyć coś w rodzaju ustawienie demo.
    I aby zawsze można by było do tej nastawy wrócić.
    Pomyślałem więc, że skoro nastawy będe mieć w strukturze, to mógłbym tylko ustawić wskaźnik typu char na jej początek, a następnie skopiować w pętli z tablicy.
    Wiem, że można inaczej, wiem że można ręcznie wpisywać, ale robię to po to aby sie nauczyć zarówno struktur , których nie używałem do tej pory, jak i wskaźników.

    0
  • Pomocny post
    #19 25 Gru 2017 18:48
    grko
    Poziom 32  

    @Marek_Gorecki to może zadeklaruj sobie strukturę z domyślnie ustawieniami jako const struct
    oraz zainicjaliuj wszystkie pola. Jak będziesz chciał wrócić do domyślnych ustawień to wystarczy ci jedno memcpy. Pomysł z tablicą i kopiowaniem w pętli nie jest do końca trafiony choćby w względu na pakowanie danych (bardziej jego brak😀) w strukturach.

    0
  • #20 25 Gru 2017 18:54
    JacekCz
    Poziom 35  

    Marek_Gorecki napisał:
    Freddie Chopin napisał:
    Marek_Gorecki napisał:
    Zapytam raz jeszcze , jak uzyskac wskaznik typu char na strykture.

    My też spytamy raz jeszcze - po co chciałbyś uzyskać wskaźnik nieprawidłowego typu, skoro widać że gubisz się na najprostszych kwestiach języka?


    Ponieważ, chciałbym zrobić sobie strukturę z wszystkimi nastawami programu.
    Program ten jest do sterowania akwarium.
    Programowane są godziny włączeń i wyłączeń różnych doświetleń ( różna kolorystyka), a ponieważ są 4 kolory, więc par czasowych włącz - wyłacz jest wiele. Jeśli do tego dołożę, że mają być też dni, aby niepotrzebnie bajery te były właczane w godzinach pracy, to robi się tego naprawdę dużo.
    I teraz chodzi mi o to, aby stworzyć coś w rodzaju ustawienie demo.
    I aby zawsze można by było do tej nastawy wrócić.
    Pomyślałem więc, że skoro nastawy będe mieć w strukturze, to mógłbym tylko ustawić wskaźnik typu char na jej początek, a następnie skopiować w pętli z tablicy.
    Wiem, że można inaczej, wiem że można ręcznie wpisywać, ale robię to po to aby sie nauczyć zarówno struktur , których nie używałem do tej pory, jak i wskaźników.


    Czyli jednak "XY problem", a od StakOverflowa różnisz się tupaniem nóżką.
    A jakby to było jeszcze przez etapem "poznania pętli" to byś pisał jeden ogromny kod? To może wymień te fragmenty C, które znasz (lub Ci się przynajmniej wydaje), będzie prościej.

    Nie podejmuję się z Twoim uporem objaśnić cokolwiek.
    Aha, jeszcze jedno, struktura jest właśnie przeznaczona do tego, do czego bardzo nie chcesz jej użyć. Ale jak wiesz lepiej ....

    0
  • #21 25 Gru 2017 18:54
    Marek_Gorecki
    Poziom 16  

    Chyba zaczyna mi coś działać.
    Otóż zrobiłem tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    I widzę w terminalu wartości 1,9,34,22.
    Więc udało mi się zrobić pierwszy krok, a mianowicie skopiować strukturę do zmiennej tablicowej.
    Teraz spróbuje zrobić odwrotnie.

    0
  • #22 25 Gru 2017 19:00
    JacekCz
    Poziom 35  

    Marek_Gorecki napisał:
    Chyba zaczyna mi coś działać.
    Otóż zrobiłem tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    I widzę w terminalu wartości 1,9,34,22.
    Więc udało mi się zrobić pierwszy krok, a mianowicie skopiować strukturę do zmiennej tablicowej.
    Teraz spróbuje zrobić odwrotnie.


    Nie dasz sobie powiedzieć, ze to undefined behaviour, a w dodatku bezcelowe?

    0
  • #23 25 Gru 2017 19:06
    Marek_Gorecki
    Poziom 16  

    Możesz wytłumaczyć Początkującemu, co to znaczy "undefined behaviour"?
    Co jest w tym kodzie źle?

    0
  • #24 25 Gru 2017 19:08
    grko
    Poziom 32  

    @Marek_Gorecki Ok.
    Osiągnąłeś to co chciałeś. Nawet zadziałało bo wszystkie pola w strukturze są typu char. Nawet zadziała odwrotna operacja. Jednak jeżeli Twoja struktura będzie miała pola innego typu niż char to ta metoda nie zadziała. Właśnie ze względu na pakowanie struktur. Kod taki również nie będzie portowalny że względu na endianes.

    @JacekCz To nie jest UB (tj rzutowanie dowolnego typu na char *). No ale pewnie to wiesz z tych wszystkich książek.

    0
  • #25 25 Gru 2017 19:19
    Marek_Gorecki
    Poziom 16  

    Sprawdziłem i działa w obie strony.
    Wystarczy tylko :

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Jak pisałem na początku, mam w strukturze tylko pola typu char.
    Tak jak wspominałem, zadanie specjalnie sobie utrudniłem edukacyjnie.

    A przy okazji , czy da się to zrobić , aby skopiować strukturę do zmiennej tablicowej, a następnie odwrotnie ale w przypadku gdy pola w strukturze będą nie tylko char?

    0
  • #26 25 Gru 2017 19:22
    JacekCz
    Poziom 35  

    grko napisał:

    @JacekCz To nie jest UB (tj rzutowanie dowolnego typu na char *). No ale pewnie to wiesz z tych wszystkich książek.


    Interpretowanie struktury jest

    0
  • Pomocny post
    #27 25 Gru 2017 19:27
    grko
    Poziom 32  

    @Marek_Gorecki Tak. Możesz tak zrobić. Jednak jeżeli struktura będzie bardziej skomplikowana to ciężko ci będzie określić gdzie są właściwe pola struktury a gdzie padding w przypadku jakbyś chciał edytować zmienne w tablicy. Weź sobie to jeszcze raz przećwicz tylko zmień środkowe pole Twojej struktury na uint32

    @JacekCz wskaż proszę w której linii jest UB

    0
  • Pomocny post
    #28 25 Gru 2017 19:55
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Marek_Gorecki napisał:
    Programowane są godziny włączeń i wyłączeń różnych doświetleń ( różna kolorystyka), a ponieważ są 4 kolory, więc par czasowych włącz - wyłacz jest wiele. Jeśli do tego dołożę, że mają być też dni, aby niepotrzebnie bajery te były właczane w godzinach pracy, to robi się tego naprawdę dużo.

    Nie widzę problemu. Struktura powinna być z parametrami JEDNEJ nastawy czasowej (dzień, godzina, minuta, sekunda). Jeśli potrzebujesz takich nastaw więcej, to wystarczy zrobić... tablicę struktur.

    Dodano po 1 [minuty]:

    grko napisał:
    @JacekCz wskaż proszę w której linii jest UB

    Umówmy się, że z opisu autora raczej nie wynika że potrzebował tego wszystkiego do wysyłania danych na terminal, tylko do czegoś innego (;

    0
  • #29 25 Gru 2017 19:58
    Marek_Gorecki
    Poziom 16  

    Sprawdziłem i działa poprzez powyższy program.
    Mogę zrobić dowolną strukturę, następnie ję skopiować do zmiennej tablicowej, po czym skopiować ją z powrotem do struktury i struktura będzie wygladać identycznie.

    0
  • #30 25 Gru 2017 20:02
    JacekCz
    Poziom 35  

    Marek_Gorecki napisał:
    Sprawdziłem i działa.
    Mogę zrobić dowolną strukturę, następnie ję skopiować do zmiennej tablicowej, po czym skopiować ją z powrotem do struktury i struktura będzie wygladać identycznie.


    You are saying something like this:

    Somebody once told me that in basketball you can’t hold the ball and run. I got a basketball and tried it and it worked just fine. He obviously didn’t understand basketball.


    A Guide to Undefined Behavior in C and C++, Part 1
    https://blog.regehr.org/archives/213

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0