Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

przesyłanie tablic do funkcji w C

Moderatorzy: Jacek Bogusz, Moderatorzy

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

przesyłanie tablic do funkcji w C

Postautor: Sławek5 » 1 cze 2006, o 03:44

Cześć.
Chcę się spytać o zasady przesyłania do funkcji tablic.

W przypadku tablic jednowymairowych. Jeśli mam 2 funkcję oraz tablicę jednowymiarową:

Kod: Zaznacz cały

char tablica[10]; void funkcja_1(char tab[], char ile) { char i; for(i=0; i<ile;i++)tab[i]=0; //np zerujemy }

oaz druga

Kod: Zaznacz cały

void funkcja_2(char *ptr, char ile) { int i; for(i=0; i<ile;i++)*ptr=0; //np zerujemy }
i wywołanie

Kod: Zaznacz cały

funkcja_1(tablica); //wyołanie 1 funkcji funkcja_2(tablica); //wywołanie 2 funkcji


Czy te obie funkcje się czymś różnia, czy jest to tylko inny zapis

A jak to wygląda dla tablic wielowymiarowych, bo tego juz w ogóle nie wiem.
Powiedzmy że mamy takie same funkcje jak wyżej ale dla tablic wielowymiarowych



I ostatnia rzecz czy można zrobić uniwersalną funkcję, która by działała dla tablic jednowymiarowych i wielowymairowych

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 10:03

1 - przekazujesz tablice

2 - przekazujesz wskaźnik

W C nie ma tablic wilowymiarowych. Tzw. tablica dwuwymiarowa to tablica (jednowymiarowa) tablic (tez jednowymiarowych)

Przyklad - jak myslisz, co wypisze program? :)

Kod: Zaznacz cały

#include <stdio.h> int tab[][2] = {1,2,3,4,5,6,7}; int main(void) { printf("%d\n", tab[1][0]); }
Ostatnio zmieniony 1 cze 2006, o 16:53 przez a_antoniak, łącznie zmieniany 1 raz.

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 cze 2006, o 10:46

Pokaże 3.

A jak z tymi tablicami wielowymiarowymi przy przesyłaniu do funkcji, mniej więcej coś podobnego jak napisałem dla jednowymairowych, jak to będzie w yym przypadku??

tomek_j
-
-
Posty: 264
Rejestracja: 14 sty 2004, o 09:06

Postautor: tomek_j » 1 cze 2006, o 11:09

Pokaże 3.

A jak z tymi tablicami wielowymiarowymi przy przesyłaniu do funkcji, mniej więcej coś podobnego jak napisałem dla jednowymairowych, jak to będzie w yym przypadku??
int tab[2][12]

fun(int tab[2][12])
{.....
}
lub
fun(int tab[][12])
{......}

lub
fun(int(*tab)[12])
{.......}
albo jakos tak. A dlaczego w C nie ma tablic wielowymiarowych jak sa? A własciwie to kwestia nazywania - moga sie nazywac jednowymiarową tablicą tablic co mi tam

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 11:28

A dlaczego w C nie ma tablic wielowymiarowych jak sa?
Dlatego, ze mozesz zadeklarowac wielowymiarowa, a odwolywac sie jak do jednowymiarowej, co w roznych pascalach czy basicach nie jest mozliwe (i moze lepiej, ze nie jest). Oczywiscie, nie przekonuje Cie to? 8)

[ Dodano: 01-06-2006, 11:31 ]
Pokaże 3.
Odgadles, czy wklepales i zobaczyles co wyszlo? :)

tomek_j
-
-
Posty: 264
Rejestracja: 14 sty 2004, o 09:06

Postautor: tomek_j » 1 cze 2006, o 11:42

A dlaczego w C nie ma tablic wielowymiarowych jak sa?
Dlatego, ze mozesz zadeklarowac wielowymiarowa, a odwolywac sie jak do jednowymiarowej, co w roznych pascalach czy basicach nie jest mozliwe (i moze lepiej, ze nie jest). Oczywiscie, nie przekonuje Cie to? 8)
Oczywiscie przekonuje, ale lubie myslec o nich jako o wielowymiarowych - lepiej sie wtedy czuję :)

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 12:17

lubie myslec o nich jako o wielowymiarowych - lepiej sie wtedy czuję :)
Bo tak wlasnie IMHO powinno byc - jak deklarujemy wielowymiarowa, to ma taka byc, a nie jakies tam dyrdymaly jak w C. Tak samo jest ze stringami (tymi informatycznymi 8) ) - jest char* i sie mecz z tym :roll: . Zawsze jest pod reka STL, tyle ze to C++, a nie C...

Guru
-
-
Posty: 250
Rejestracja: 30 cze 2003, o 13:26
Lokalizacja: Kraków

Postautor: Guru » 1 cze 2006, o 12:37

Nie wiem skąd to się wzięło że w C nie ma tablic wielowymiarowych. Pracowałem z różnymi kompilatorami i zawsze da się zadeklarowac tablicę wielowymiarową, a jej deklaracja wygląda następująco:

Kod: Zaznacz cały

int tab[][2] = {{1,2},{3,4},{5,6},{7,9}};
a nie tak jak to pokazano w poprzednim przykładzie:

Kod: Zaznacz cały

int tab[][2] = {1,2,3,4,5,6,7};
- tak inicjuje się niestety tablicę jednowymiarową. Większość kompilatorów zgłosi błąd, a przynajmniej powinno.

Jeżeli chodzi o przekazywaniu tablic do funkcji to w C możesz to robic tylko przez wskaźnik, niejako nazwa tablicy jest wskaźnikiem na pierwszy jej element.

W przypadku funkcji uniwersalnej należy rzutować wskaźnik do tablicy na wskaźnik do elemntów tablicy. Czyli taka funkcja będzie mogła wyglądać następująco:

Kod: Zaznacz cały

fun (char *wsk) { };
i wywołanie

Kod: Zaznacz cały

fun(nazwa_tabl);
dokonujemy tutaj niejawnej konwersji typów chociaż można się z tym nie zgodzić z powodów powyższych.
Ostatnio zmieniony 2 cze 2006, o 07:34 przez Guru, łącznie zmieniany 2 razy.

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 cze 2006, o 12:39

Szczerze!

Wklepałem i zobaczyłen co pokarze AVRStudio. Jest oczywiście prymitywny wzorek ale...


a_antoniak, wracając do mojej taklicy wielowymarowej. Jeśli mogę Cię prosić to napisz jak to ma być (o czym pisałem na samym początku) Please!!

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 12:50

Nie wiem skąd to się wzięło że w C nie ma tablic wielowymiarowych. Pracowałem z różnymi kompilatorami i zawsze da się zadeklarowac tablicę wielowymiarową, a jej deklaracja wygląda następująco:

Kod: Zaznacz cały

int tab[][2] = {{1,2},{3,4},{5,6},{7,9}};
Po tym mozesz sobie pochodzic jak po 1-wymiarowej jesli zechcesz :)
a nie tak jak to pokazano w poprzednim przykładzie:

Kod: Zaznacz cały

int tab[][2] = {1,2,3,4,5,6,7};
- tak deklaruje się niestety tablicę jednowymiarową.
DEKLARACJA jest dwuwymiarowej, zaś INICJALIZACJA jednowymiarowej, co najlepiej potwierdza dwoistosc tablicowej natury w C. W obu podanych przez Ciebie przypadkach deklaruje sie tab. 2-wymiarowa, tylko inaczej inicjalizuje.
Ostatnio zmieniony 1 cze 2006, o 16:47 przez a_antoniak, łącznie zmieniany 1 raz.

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 cze 2006, o 13:48

Zapytam wprost.

Jak przesłać do funkcji tablicę wielowymiarową i na niej operować.

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty: 2650
Rejestracja: 24 sty 2005, o 00:39
Lokalizacja: Winny gród

Postautor: pajaczek » 1 cze 2006, o 14:19

Kod: Zaznacz cały

int tab[][2] = {1,2,3,4,5,6,7};
- tak deklaruje się niestety tablicę jednowymiarową.

Jeżeli chodzi o przekazywaniu tablic do funkcji to w C możesz to robic tylko przez wskaźnik, niejako nazwa tablicy jest wskaźnikiem na pierwszy jej element.
Tak deklaruje sie tablice 2 wymiarowa, tyle ze inicjowana jest jak 1 wymiarowa (dodatkowo okresla sie jej rozmiar - na podstawie inicjacji - na 8 elementow, czy inaczej rozmiar na 4x2), pamietaj ze deklaracja:

Kod: Zaznacz cały

int tab[4][2];
rezerwuje poprostu 8 kolejnych miejsc w pamieci.

I druga rzecz, dlaczego "tylko" ? mozna przekazac przez wskaznik, albo bezposrednio. Tyle ze przekazujac bezposrednio, 1) pracujemy na kopii, 2) marnujemy czas procesora i pamiec, 3) dodatkowo musimy zrobic cos z wynikiem funkcji (bo po wyjsciu z funkcji kopia poprostu zniknie - pamiec zostanie zwolniona).
Dlatego wszedzie zaleca sie przekazywanie nie tylko tablic, ale wszelkich duzych struktur przez wskazniki ;) (no... chyba ze to ma jakis inny sens).
Nie wiem skąd to się wzięło że w C nie ma tablic wielowymiarowych. Pracowałem z różnymi kompilatorami i zawsze da się zadeklarowac tablicę wielowymiarową, a jej deklaracja wygląda następująco:

Kod: Zaznacz cały

int tab[][2] = {{1,2},{3,4},{5,6},{7,9}};
Po tym mozesz sobie pochodzic jak po 1-wymiarowej jesli zechcesz :)
Tak... jesli zechcesz, co nie znaczy ze musisz, wiec jaki problem ?? Jak Ci pasuje poruszaj sie jak po wielowymiarowej.
DEKLARACJA jest dwuwymiarowej, zaś INICJALIZACJA jednowymiarowej, co najlepiej potwierdza dwoistosc tablicowej natury w C. W obu podanych przez Ciebie przypadkach deklaruje sie tab. 2-wymiarowa, tylko inaczej inicjalizuje.
Sposob inicjalizacji wielowymiarowej juz Guru podal, wiec... mozesz zanicjowac tak albo tak, wiec znow w czym problem ?? Deklaruj jak Ci wygodniej (a nie tak jak narzucaja inne jezyki) wiec to tez nie problem a zaleta!

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 14:34

wiec jaki problem ??
O co Ci chodzi z tym problemem? Napisales dokladnie to samo co wczesniej ja, a potem zacytowales to i ... ze jakis problem....

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty: 2650
Rejestracja: 24 sty 2005, o 00:39
Lokalizacja: Winny gród

Postautor: pajaczek » 1 cze 2006, o 14:41

O to:
Dlatego, ze mozesz zadeklarowac wielowymiarowa, a odwolywac sie jak do jednowymiarowej, co w roznych pascalach czy basicach nie jest mozliwe (i moze lepiej, ze nie jest).
a szczegolnie o ten nawias, brzmi tak, jakby to byl dla Ciebie jakis problem :roll: Caly czas piszesz (a moze tylko ja to tak odbieram), ze obsluga wielowymiarowej tablicy jako 1 wymiarowej to utrudnienie. Podczas gdy nie jest to wcale obowiazkowe.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 14:57

O to:
Dlatego, ze mozesz zadeklarowac wielowymiarowa, a odwolywac sie jak do jednowymiarowej, co w roznych pascalach czy basicach nie jest mozliwe (i moze lepiej, ze nie jest).
a szczegolnie o ten nawias, brzmi tak, jakby to byl dla Ciebie jakis problem :roll: Caly czas piszesz (a moze tylko ja to tak odbieram), ze obsluga wielowymiarowej tablicy jako 1 wymiarowej to utrudnienie. Podczas gdy nie jest to wcale obowiazkowe.
Spiesze z wyjasnieniem :). To refleksja o jezyku, a nie stwierdzenie, ze cos jest zle bo ja tego nie rozumiem (to dla mnie problem). Nie jest to dla mnie problemem, ani utrudnieniem w uzywaniu C. Przeciwnie - zwykle mysle o wielowym. jak o 1-wym. - tak mi wygodniej :). Ale IMHO w praktyce daje to wiecej pol do popelniania bledow niz do sensownego wykorzystania. Oczywiscie to tylko moja opinia :);

[ Dodano: 01-06-2006, 17:25 ]
Zapytam wprost.

Jak przesłać do funkcji tablicę wielowymiarową i na niej operować.
Mozesz to zrobic najprosciej, lub przez wskaznik. Niezaleznie od sposobu, do elementow mozesz odwolywac sie przez wskaznik lub zwyczajnie. Ponizej wszystkie sposoby odwolania dadza w wyniku 8. Trzeba pamietac, ze to tablica tablic (najlepiej narysowac sobie rozpiske na kartce):

Kod: Zaznacz cały

#include <stdio.h> //przekazujemy tablice 2-wymiarowa void fun1(char tab[][2]) { printf("%d\n",tab[3][1]); printf("%d\n",(*(tab+3))[1]); printf("%d\n",*(*(tab+3)+1)); } //przekazujemy wskaznik do tablicy 1-wymiarowej, 1-go elementu tablicy 2-wymiarowej void fun2(char (*p_tab)[2]) { printf("%d\n",p_tab[3][1]); printf("%d\n",(*(p_tab+3))[1]); printf("%d\n",*(*(p_tab+3)+1)); } int main() { char tablica[][2]={1,2,3,4,5,6,7,8,9}; fun1(tablica); fun2(tablica); return 0; }
Dotyczy fun2: z przekazywaniem tablic przez wskaznik generalnie zasada jest taka, ze (po prostu) przekazuje sie wskaznik do pierwszego elementu tablicy. A poniewaz w przypadku tablicy 2-wymiarowej pierwszym elementem jest tablica 1-wymiarowa, to wskaznik do niej jest przekazywany do funkcji fun2.

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 1 cze 2006, o 19:12

Powiedz mi dlaczego i jak działa taki kod:

Kod: Zaznacz cały

char tablica[4][3]; //powiedzmy że ma ona jaieś wartości ..... void funkcja(char *ptr) { ..... }

A teraz wywołanie

Kod: Zaznacz cały

funkcja((char*)tablica);



Zastosowano rzutowanie,ale ... typu char na char ???

Awatar użytkownika
pajaczek
Moderator
Moderator
Posty: 2650
Rejestracja: 24 sty 2005, o 00:39
Lokalizacja: Winny gród

Postautor: pajaczek » 1 cze 2006, o 21:03

Zastosowano rzutowanie,ale ... typu char na char ???
Raczej typu "wskaznik na char" na "wskaznik na char". To tak proforma pewnie.

a_antoniak
-
-
Posty: 645
Rejestracja: 13 sty 2005, o 18:38
Lokalizacja: Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 1 cze 2006, o 22:22

Powiedz mi dlaczego i jak działa taki kod: ...
A dziala? Pewnie sie kompiluje :). Rzutujesz wskaznik do 1-wymiarowej tablicy char-ów na wskaznik do char. Nie wiem, do czego to sie moze przydac :). Natomiast rzutowanie przechodzi, bo wskazniki de facto sa liczbami, a rzutowanie to nic innego jak powiedzenie kompilatorowi, aby dana liczbe inaczej zinterpretowal. Zwlaszcza takie zwykle rzutowanie (wymuszone) - nie oglada sie prawie na nic :).

Sławek5
-
-
Posty: 485
Rejestracja: 15 sie 2003, o 16:40
Lokalizacja: Szczecin
Kontaktowanie:

Postautor: Sławek5 » 2 cze 2006, o 06:26

Chciałem wrócić do Twojego przykładu

Kod: Zaznacz cały

//przekazujemy tablice 2-wymiarowa void fun1(char tab[][2]) { printf("%d\n",tab[3][1]); printf("%d\n",(*(tab+3))[1]); printf("%d\n",*(*(tab+3)+1)); } //przekazujemy wskaznik do tablicy 1-wymiarowej, 1-go elementu tablicy 2-wymiarowej void fun2(char (*p_tab)[2]) { printf("%d\n",p_tab[3][1]); printf("%d\n",(*(p_tab+3))[1]); printf("%d\n",*(*(p_tab+3)+1)); }

Trochę niejasne jest dla minie jak się poruszać po takiej tablicy przekazanej do funkcji.
Jeżeli przekazana jest tablica o n wierszach i k kolumnach to to odbierając ją w funkcji która liczba (mówiąc obrazowo) jest n a która to k w tych przykładach.
Oczywiście te przykłady działają, bo sprawdzałem.

Guru
-
-
Posty: 250
Rejestracja: 30 cze 2003, o 13:26
Lokalizacja: Kraków

Postautor: Guru » 2 cze 2006, o 07:25

Jeżeli mnie pamięć nie myli to w C

NIE MA MOŻLIWOŚCI PRZEKAZANIA TABLICY DO FUNKCJI PRZEZ WARTOŚĆ

tak więc zapisy

Kod: Zaznacz cały

fun(tabl[])
oraz

Kod: Zaznacz cały

fun(tabl)
czy też

Kod: Zaznacz cały

fun((char*)tabl)
robią to SAMO przekazują do funkcji adres pierwszego elementu tablicy,
a funkcja do której przekazywana jest tablica też operuje na wskaźniku do niej.

Wróć do „PLD/FPGA i inne zagadnienia techniki cyfrowej”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 13 gości