Rozmiar tablicy - jak odczytać

0

Witam! Widziałem wiele podobnych tematów, lecz w żadnym nie jest dokładnie napisane jak odczytać rozmiar tablicy. Napisałem program do sortowania bąbelkowego i do parametrów tej funkcji chcę tylko wstawiać tablicę. Jak wyciągnąć rozmiar jeżeli np. wstawiam sobie tablice[100] to wyciągnę 100. Próbowałem sizeof(tablica), ale zawsze zwraca 4 od int to samo sizeof(*tablica) zawsze 4. Więc nie mogę pamięci podzielić na rozmiar int :( Jak to zrobić?

0
arraySize = sizeof(array)/sizeof(array[0]);

wg tego co na necie to powinno zadziałać (czyli sizeof(tablica) powinno zwrócić ilość bajtów zarezerwowanych na twoją tablicę)
Może dałbyś radę skorzystać z wektorów?
BTW. Nie jest możliwe "sprawdzenie" wielkości tablicy, jeżeli robisz to np w innej funkcji do której jako parametr przekazałeś wskaźnik na pierwszy jej element.

0

Z tego co napisałeś wyjdzie mi 1 (4 / 4 = 1) Mówię, sizeof(tablica) zwraca mi 4 nie wiem dlaczego zamiast całkowitej pamięci. Obojętnie czy tablica jest 10 czy 1000 elementowa zwraca 4. :(

0

Ja jak masz deklarację tablicy?

int tab[10];
size_t len = sizeof(tab) / sizeof(tab[0]); // długość tablicy

int *p_tab = tab; //< nedase
int *d_tab = new int[10]; //< nedase
0

@gienek jeśli o tablica dynamiczna, albo zrzutowana do wskaźnika to zapomnij, bo się nie da.

0

Zwykła tablica jak w szkole :D Hmm... Zrobiłem nowy projekt i działa z sizeof(tablica) / sizeof(int) (przykładowo) I wiem, że w funkcji nie działa. Parametry takie:
int bubbleSort(int *tablica) i nie działa dlatego, że to wskaźnik? Jak zrobić ze wskaźnikiem, aby działało jak wyżej?

1

Napisałem niewyraźnie? NIE DA SIĘ. Musisz przekazać do funkcji rozmiar, ot cała filozofia.

0
  1. sizeof(tablica) / sizeof(typ_tablicy) - ogólny wzór na obliczanie wielkości tablicy
  2. W funkcji nie można użyć sizeof(tablicy) !!! (poczytaj sobie o przekazywaniu tablicy do funkcji)
0

Ludze, co Wy gadacie ?! Tak, jak mówi Shalom - NIE DA SIĘ ! Chyba Wam się myli z tym, jak się liczy rozmiar tablicy dynamicznej do malloca ;p (ilość_elem * rozmiar_komórki)
@gienek: przekazuj do funkcji drugi parametr - rozmiar przekazywanej tablicy !

0

Nawet tak się nie da ;) Choć robi dobre wrażenie. ;) W C przynajmiej. Przekazywany jest wskaźnik.

#include <stdio.h>

void huhu ( char t[20] ) {

int i;

for (i=0; i<20; i++ )
  fprintf( stdout, "%u", t[i] );

fprintf( stdout, "\nrozmiar t: %lu\n" , sizeof(t) );
}

int main (int argc, char *argv[]) {

char y[20];
int i;

for (i=0; i<20; i++ )
  y[i] = i;

huhu ( y );

return 0;
}

Dodane:
Rozmiar tablicy da się policzyć, tylko nie da się przekazać całej tablicy jako parametru do funkcji.
A jak nie mamy przekazanej tablicy to policzyć możemy jedynie to co się do funkcji przekazało czyli wskaźnik.

0

To, że mogę przekazać wielkość tablicy to wiem, ale to takie dziwne rozwiązanie dla mnie się wydaje. Chciałem to uprościć. Jeżeli nie ma innego wyjścia to trudno, zrobiłem trochę inaczej, nie przekazuję wielkości tylko mam ją w zmiennej globalnej i sobie z funkcji ją odczytuję. Przynajmniej tak jest trochę bardziej estetycznie :) Ale dzięki za pomoc wszystkim.

0

Jeśli chcesz estetyczniej to ja bym użył struct Zmienne globalne tablic są bezsensowne. Ujdą w małym programie na kilka linijek. A jak jeszcze wpadniesz w wielowątkowość albo będziesz potrzebował rozpączkować te tablice, albo zaaplikować swoje dzieło do nowego programu, to już w ogóle nie będziesz wiedział co się dzieje ze zmiennymi globalnymi a która zmienna jest do której tablicy ;) Na dodatek będziesz musiał każdą funkcje przepisać.

0
gienek napisał(a)

To, że mogę przekazać wielkość tablicy to wiem, ale to takie dziwne rozwiązanie dla mnie się wydaje. Chciałem to uprościć. Jeżeli nie ma innego wyjścia to trudno, zrobiłem trochę inaczej, nie przekazuję wielkości tylko mam ją w zmiennej globalnej i sobie z funkcji ją odczytuję. Przynajmniej tak jest trochę bardziej estetycznie :) Ale dzięki za pomoc wszystkim.

Zmienne globalne nie są bardziej estetyczne niż funkcja przyjmująca jako drugi parametr dlugosc tablicy.

0

No nie wiem. Może i fakt :) Zrobiłem dynamiczną tablicę i z drugim parametrem ;D

0

Teoretycznie się da, można wykorzystać z implementacji malloca, zwykle we wcześniejszych bajtach tablicy będzie jej wielkość (a dokładniej ilość pamięci zaalokowanej), ale np. w glibc z uwzględnieniem wielkości dodatkowych informacji potrzebnych do zwolnienia pamięci (w glibc jest to t[-1], gdzie t to adres zajętej pamięci). Nie jest to ani dobra, ani szybka, ani ładna, ani przenośna metoda, ale ten problem mnie po prostu zaintrygował.

0

To, że mogę przekazać wielkość tablicy to wiem, ale to takie dziwne rozwiązanie dla mnie się wydaje
Niestety, C i C++ są pod tym względem bardzo prymitywne. Tablica jest przekazywana w postaci wskaźnika na nią (czyli wskaźnika na pierwszy element), a rozmiar jest tracony.

ciekawe, nie wiedziałem że przed samą tablicą jest informacja odnośnie jej rozmiarów. Na uczelni na podstawach ANSI C nie wspomniano nawet o tym
Bo to nie należy do ANSI C, lecz jest cechą konkretnego kompilatora czy biblioteki. Raczej nie należy na tym polegać: teoretycznie w każdej wersji może się to zmienić.

0

ogólnie rzecz biorąc sprawdzając rozmiar tablicy przekazanej do funkcji przez wskaźnik w rzeczywistości sprawdza się rozmiar wskaźnika, który na platformach 32 bitowych jest równy 4 bajty (ale nie jest to wcale zasada i tak nie musi być, może on posiadać inny rozmiar). sizeof w tym wypadku zwraca jego wielkość, a nie rzeczywistej tablicy, dlatego na nim nie warto polegać. Lepiej w takiej sytuacji przekazać wielkość w argumencie funkcji, albo jeszcze lepiej opakować tablice w klasę i zadbać o jej funkcjonalność, jednak zastosowanie stl'a i kontenerów z niego byłoby najładniejszym i zapewne najlepszym rozwiązaniem.

0

taka opakowana tablica istnieje w bibliotece BOOST:

#include <boost\array.hpp>
#include <iostream>
using namespace std;

typedef boost::array<int,10> tablica;

void foo(tablica &tab)
{
	for (int i=0;i<tab.size();i++)
		cout<<tab[i]<<endl;
}

int main()
{
	tablica arr = {1,2,3,4,5,6,7,8,9,10};
	foo(arr);
}
0
Zjarek napisał(a)

Teoretycznie się da, można wykorzystać z implementacji malloca, zwykle we wcześniejszych bajtach tablicy będzie jej wielkość (a dokładniej ilość pamięci zaalokowanej), ale np. w glibc z uwzględnieniem wielkości dodatkowych informacji potrzebnych do zwolnienia pamięci (w glibc jest to t[-1], gdzie t to adres zajętej pamięci). Nie jest to ani dobra, ani szybka, ani ładna, ani przenośna metoda, ale ten problem mnie po prostu zaintrygował.

Ta metoda jeszcze ma wade, w domyśle zakłada że przekaże się początek tablicy z malloc ;) Ciekawe kto z was patrzący na prototyp funkcji

void rozjasnij( int * , int * );

Będzie wiedział co tam trzeba przekazać?

A dla mnie ten problem jest jakiś dziwny. A to z tego powodu że w praktyce operujemy na danych. A nie na tablicach. Myśle że ten problem z tablicami dotyczy głównie początkujacych. Jeśli rozmiar tablicy może być inny to i dane są różne. A jeśli alokujemy dynamicznie to i sizeof nie działa. Po co więc sobie utrudniać życie? To już jest dylemat raczej filozoficzny.

0

Ciekawe kto z was patrzący na prototyp funkcji Będzie wiedział co tam trzeba przekazać?
z dokumentacji.

Jeśli rozmiar tablicy może być inny to i dane są różne
Czasami tak, czasami nie — w przypadku jakiegoś bufora, czy choćby c-stringa, musimy wiedzieć, czy miejsca wystarczy.

0
Azarien napisał(a)

Ciekawe kto z was patrzący na prototyp funkcji Będzie wiedział co tam trzeba przekazać?
z dokumentacji.

Imho, dodatkowa złożoność. Tylko czy potrzebna?

Azarien napisał(a)

Jeśli rozmiar tablicy może być inny to i dane są różne
Czasami tak, czasami nie — w przypadku jakiegoś bufora, czy choćby c-stringa, musimy wiedzieć, czy miejsca wystarczy.

W sumie racja, bo jesteśmy ograniczeni miejscem. Ale dalej jest to jakby "prośba odbierz ileś danych". A nie, odbierz tablice danych. Przynajmniej dla mnie ;) Niby to samo a nie to samo ;) W przypadku ileś danych, zapewniamy wcześniej miejsce na te dane, lub też mamy funkcje która robi to sama.

1 użytkowników online, w tym zalogowanych: 0, gości: 1