logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak zwrócić tablicę dwuwymiarową z funkcji w C? Kod i błędy kompilacji

mikroproc 27 Lut 2013 00:23 4815 19
REKLAMA
  • #1 11992347
    mikroproc
    Poziom 9  
    Witam,

    Mam następujący problem.
    Potrzebuje napisać funkcję, która będzie zwracała tablicę dwuwymiarową.
    Deklaracja tablicy oraz jej wartości koniecznie muszą być wewnątrz funkcji i ta tablica będzie dalej wykorzystywana.

    Bardzo proszę o pomoc.

    Kod mojej funkcji:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Otrzymuję następujące błędy:

    funkcje.c: In function 'Dane':
    funkcje.c:47: error: expected expression before '{' token
    funkcje.c:60: warning: return from incompatible pointer type
    funkcje.c:60: warning: function returns address of local variable
    funkcje.c:64: error: expected expression before '{' token
    funkcje.c:75: warning: return from incompatible pointer type
    funkcje.c:75: warning: function returns address of local variable
    make.exe: *** [funkcje.o] Error 1
  • REKLAMA
  • REKLAMA
  • #3 11992455
    Tomiks
    Poziom 13  
    Cytat:
    Potrzebuje napisać funkcję, która będzie zwracała tablicę dwuwymiarową.

    To niemożliwe w C.

    Mógłbyś co prawda zwrócić z funkcji wskaźnik do takiej tablicy, ale tu także problem, bo nie może to być lokalna tablica utworzona wewnątrz tej funkcji, gdyż po wyjściu z funkcji pamięć tablicy, do której zwracasz wskaźnik będzie zwolniona.

    Może utwórz tablicę przed wywołaniem funkcji i przekaż do niej jej wskaźnik w dodatkowym parametrze, aby mogła w niej poustawiać wartości w zależności od przypadku.
  • REKLAMA
  • #4 11992462
    mickpr
    Poziom 39  
    Tomiks napisał:
    To niemożliwe w C.


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kompilujący się kod.

    Ale .. przyznam.. jak to widzę, to mnie skręca.
    Rozwiązanie problemu jest kiepskie.
    Aby upewnić się co do istnienia zmiennych powinno się je dodatkowo zadeklarować jako static. Inaczej mogą być niedostępne. Tutaj są wstawione w plik (jedynego) modułu głównego... więc jest ok.
  • #5 11992475
    prawicowiec
    Poziom 9  
    witam

    pomiędzy case musisz tak wypełniać tablice

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #6 11992619
    BlueDraco
    Specjalista - Mikrokontrolery
    1. Nie zwraca się struktur jako wartości funkcji. Nie dlatego, że język na to nie pozwala, a dlatego, że nie ma to sensu i dużo kosztuje.

    2. Procedura, która woła Twoją procedurę powinna zaalokować (zdefiniować) tablicę i przekazać wskaźnik na nią do procedury, która ma ją wypełnić.

    3. Funkcja nie może zwrócić wskaźnika na swoją zmienną lokalną (dynamiczną automatyczną), bo ta zmienna przestaje istnieć z chwilą zakończenia wykonania funkcji.
  • REKLAMA
  • #7 11992644
    mickpr
    Poziom 39  
    BlueDraco napisał:
    Procedura, która woła Twoją procedurę powinna zaalokować (zdefiniować) tablicę
    Nie do końca się zgodzę się - chyba, że tablica ma być potem "zapisywalna",
    O wiele lepiej ZADEKLAROWAĆ tablicę jako stałą - w obszarze PROGMEM.
    Rozwiązanie, które przedstawiłem - jest zgodne z regułami języka C, ale wielce nieoptymalne w przypadku mikrokontrolerów.
  • #8 11992702
    BlueDraco
    Specjalista - Mikrokontrolery
    Jeśli to jest tablica o stałej zawartości, to oczywiście tak, ale tym bardziej należy zwracać wskaźnik.
  • #9 11992727
    mickpr
    Poziom 39  
    BlueDraco napisał:
    ale tym bardziej należy zwracać wskaźnik.
    Zwracanie wskaźnika jest jedynym poprawnym (i dostępnym) sposobem w "C" w tym przypadku.
  • #10 11992742
    BlueDraco
    Specjalista - Mikrokontrolery
    Teoretycznie poprawnie można zwrócić strukturę (np. zwierającą tablicę) przez wartość, ale zdecydowanie nie należy tego robić.
  • #11 11993580
    mikroproc
    Poziom 9  
    Dziękuję wszystkim za pomoc i wskazówki.
    Problem został rozwiązany.

    Poniżej zamieszczam ostateczne rozwiązanie.
    W razie jakichś uwag, proszę o komentarze.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #12 11993598
    mickpr
    Poziom 39  
    Uwagi?
    Przekazywanie tablicy w ten sposób = rozrzutne gospodarowanie stosem (czyli wielki błąd).
  • #13 11993614
    mikroproc
    Poziom 9  
    mickpr napisał:
    Uwagi?
    Przekazywanie tablicy w ten sposób = rozrzutne gospodarowanie stosem (czyli wielki błąd).


    Jestem początkującym programistą, więc może rozwiniesz ten temat
    (wytłumaczysz o co chodzi) i zaproponujesz jakiś przykładowy kod, działający
    podobnie jak ten który przedstawiłem wyżej?
  • #14 11994040
    mickpr
    Poziom 39  
    mikroproc napisał:
    Jestem początkującym programistą, więc może rozwiniesz ten temat
    (wytłumaczysz o co chodzi) i zaproponujesz jakiś przykładowy kod, działający
    podobnie jak ten który przedstawiłem wyżej?

    Zaproponowałem swój kod już :)
    Jedno pytanie:
    Czy tablice zawierają wartości, które są stałe, czy się zmieniają w czasie wykonywania programu?
  • #15 11994303
    miszcz310
    Poziom 24  
    Jak mogę to ja też wrzucę swoje 3 grosze.
    W ogóle pierwsze pytanie czy to ma być program na AVR, czy zwykły na komputer?
    Moim zdaniem jak zwykły na komputer to najlepsze podejście moim zdaniem zaproponował kolega BlueDraco. To znaczy dynamiczne tworzenie takiej tablicy. Ja bym to jeszcze zamknął w strukturze, z wymiarami dokładnymi takiej macierzy. Chodzi mi o to, żeby ten kod był w ogóle jakoś przenośny, a nie tylko działało dla macierzy 8x4. Poza tym wypełnianie tej tablicy to jest masakra... Nie wierze, że nie ma jakieś algorytmu do wypełniania tej tablicy, którego nie dałoby się inaczej zapisać· Nie wiem po co Ci ta tablica i? przecież przekazujesz przez referencje.
  • #16 11994312
    BlueDraco
    Specjalista - Mikrokontrolery
    Po co pisać długi program, który zapisuje stałe do zmiennej tablicy, skoro można te stałe trzymać w tablicach jako stałe, i tylko pokazywać, którą tablicę wybrać - odpadają wtedy wszystkie macierz[][] = cośtam.

    Nie potrzebujesz tych podstawień w ogóle. Wystarczy zdefiniować tablice stałych.

    coś takiego:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a potem np.:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #17 11994796
    mickpr
    Poziom 39  
    miszcz310 napisał:
    Moim zdaniem jak zwykły na komputer to najlepsze podejście moim zdaniem zaproponował kolega BlueDraco. To znaczy dynamiczne tworzenie takiej tablicy.
    Z którego się moim zdaniem słusznie potem wycofał.
    Tworzenie zmiennej w funkcji, która ma ją zwracać to w istocie karkołomne zajęcie. (wszystko sie da zrobić) . A takie rozwiązanie podsunął nam na samym początku autor postu.

    Dlatego powtórzę po raz kolejny.
    Zadeklaruj swoje zmienne tablicowe jako typ const z atrybutem PROGMEM.
    Deklarując - zdefiniuj ich zawartość od razu.
    Potem - posługuj się wskaźnikiem na ich pierwszy element.

    To co napisał miszcz310 ma się nijak do AVR, ani do C.
    Takie zabawy można czynić jak się ma dużo pamięci RAM oraz do dyspozycji język C++.
    Jednak dalej uważam, że posłużenie się wskaźnikiem będzie szybsze.
  • #18 11995828
    miszcz310
    Poziom 24  
    mickpr napisał:

    To co napisał miszcz310 ma się nijak do AVR, ani do C.
    Takie zabawy można czynić jak się ma dużo pamięci RAM oraz do dyspozycji język C++.
    Jednak dalej uważam, że posłużenie się wskaźnikiem będzie szybsze.


    Napisałem, że to ma być dla wersji na komputer. Nie wiem dlaczego ma być to wolniejsze i dlaczego potrzebuję do tego C++. Ja bym wolał to wszytko zamknąć w strukturze na wzór klasy w C++, albo Javie. Wtedy uzyskałbym modularność. Nigdzie nie widzę, żeby tutaj była mowa o programie w C dla AVR. A nawet jeśli tak to i tak napisałem że to dla wersji na komputer. W mojej wersji też przekazywany by był tylko wskaźnik.
  • #19 11996508
    mickpr
    Poziom 39  
    miszcz310 napisał:
    Nigdzie nie widzę, żeby tutaj była mowa o programie w C dla AVR
    A w jakim dziale forum się znajdujesz?
    Już się tak nie denerwuj - bo nie o to tu chodzi. Ty patrzysz pod kątem programu na PC, a tu dział AVR! :)
  • #20 11996875
    miszcz310
    Poziom 24  
    mickpr napisał:

    miszcz310 napisał:
    Nigdzie nie widzę, żeby tutaj była mowa o programie w C dla AVR
    A w jakim dziale forum się znajdujesz?
    Już się tak nie denerwuj - bo nie o to tu chodzi. Ty patrzysz pod kątem programu na PC, a tu dział AVR! :)


    Faktycznie. Wchodziłem przez główną. Ja jestem daleki od stanu zdenerwowania :P. Faktycznie dla AVR to jest trochę za ciężkie podejście (no chyba, że dla tych największych), ale i tak sposób wypełniania tych macierzy to jest dla mnie nieuzasadniony (ten przedstawiony przez autora), przez chociażby swoją nieczytelność.
REKLAMA