Funkcja zliczająca ilość elementów tablicy

Funkcja zliczająca ilość elementów tablicy
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Potrzebuje zrobić funkcje, która przyjmuje tylko wskaznik tab i zliczy ilosc elementów tablicy.
Próbowałem zrobić sizeof(a)/sizeof(a[0]); bo znalazłem coś takiego w internecie ale albo źle wpisuję dane albo nie wiem, bo nie wychodzi poprawnie. Prosiłbym o tę mała pomoc żebym mógł iść dalej z zadaniem ;D

Kopiuj
#include <stdio.h>
int tab_size(const int* tab);
int main()
{
    int a[100];
    int *tab=&a[0];
    int i=0;
    int podana;
    int size = 0;
    
    //wypelnienie tablicy
    for(i=0;i<100;i++)
    {   
    printf("Podaj %d liczbe calkowita: ",i);
    scanf("%d",&podana);
    if(podana==-1)
			{
		
			printf("koniec\n");
			break;
			}
			
			else
			{
    		*(tab+i)=podana;
    		printf("Wpisana liczba: %d\n",*(tab+i));
			size++;	
			}
         
    }

    //wyswietlanie
    printf("\nwyjscie: \n");
    for(i=0;i<size;i++)
    {
    printf("%d ", *(tab+i));
    }
    tab_size(tab);
}
// zliczenie ilosci elementow tablicy
int tab_size(const int* tab)
{
	printf("\n \n \n%d",*(tab));
	
	return 0;
}
edytowany 1x, ostatnio: flowCRANE
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około godziny
3

od C++17 jest std::size https://en.cppreference.com/w/cpp/iterator/size
w C nie ma analogicznego rozwiązania.

Twoje rozwiązanie nie działa, bo wiedza o rozmiarze tej tablicy istnieje tylko w czasie kompilacji.
Konwertując tablicę na wskaźnik przez użycie twojej funkcji tab_size, informacja ta jest tracona i ta funkcja nie ma możliwości jej odtworzenia.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Co w takiej sytuacji powinienem zrobić? Najpierw dążyłem do samego wypisania elementów tablicy z użyciem wskaźnika itd, a teraz wziąłem się za zliczanie elementów w tablicy.

W kodzie jak widać już próbowałem liczyć elementy tablicy poza funkcją i wszystko działało. Jednak właśnie w funkcji nie wiem jak do tego podejść. Nie mogę przyjąć do funkcji nic innego poza wskaźnikiem do tablicy :/

Althorion
Moderator C/C++
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 15 godzin
  • Postów:1607
0
wiezaawieza napisał(a):

Potrzebuje zrobić funkcje, która przyjmuje tylko wskaznik tab i zliczy ilosc elementów tablicy.

To jest cel sam w sobie, czy tylko środek do jakiegoś większego celu? Bo może po prostu byłyby Ci lepiej używać jakiegoś kontenera z biblioteki standardowej, zamiast się męczyć na nagich tablicach.

edytowany 1x, ostatnio: Althorion
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 8 godzin
  • Postów:4943
0

Nie Dasz rady w ten sposób, Zobacz tutaj:
http://c-faq.com/aryptr/aryptrparam.html
Jest tak jak Napisałeś, w funkcji jest wskaźnik, a nie tablica, więc sizeof(arr)/sizeof(arr[0]); nie zadziała. Jak Chcesz takiej funkcjonalności, to, jak napisano powyżej, Użyj, np., wektora z std, albo napisz Swój.


flowCRANE
IMO ten wątek dotyczy gołego C, więc wektory i std odpadają.
lion137
No tak, rzeczywiście, to trzeba skrobnąć swoją arrayList:)
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Treść zadania:

Dana jest tablica typu int (np: {16909060, 84281096, 151653132, -1}). Zakładając, że -1 jest znacznikiem końca tablicy (nie wartością), napisz program, który pobierze od użytkownika tablicę liczb całkowitych (nie więcej niż 100), a następnie policzy i wyświetli liczbę danych w tablicy (tutaj 3). Zliczanie elementów powinno odbywać się w funkcji tab_size, o następującym prototypie:

int tab_size(const int* tab);
Parametry:

tab - wskaźnik na tablicę typu int, dla której ma zostać wyznaczona liczba elementów.


Dlatego najpierw zrobiłem taki program który wypełnia tablicę, a potem wypisuje. Tylko jak tu przerobić program tak żeby zrobić to zliczanie za pomocą funkcji?
Z wektorów std ani nic takiego nie korzystałem więc ciężko by mi było.

lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 8 godzin
  • Postów:4943
1

Rozumiem, że taki mały haczek:) nie przejdzie:

Kopiuj
#define len(array) (sizeof((array))/sizeof((array)[0]))

int main(void)
{
    int arr_int[]={1, 2 ,3, 4};
    printf("%u\n", len(arr_int));
    return 0;
}

Ale jeśli -1 jeden jest końcem tablicy, to można topornie, wysłać wskażnik do niej do funkcji i tam iterować (inkrementując licznik), aż do napotkania -1 i zwrócić wynik.


kq
Nie widzę tu funkcji tab_size ;​)
lion137
Ja też nie widzę, ale gdyby tak: funkcja to procedura, procedura to kawałek kodu, który się wykonuje gdy wpisać jej nazwę, to procedura to makro. Czyli funkcja to makro i również makro to funkcja. Koniec dowodu!:)
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Wypróbuję coś takiego. Też się zastanawiam czy przejdzie - kod sprawdza maszyna uczelniowa więc najwyżej wypluje błąd, bo jej się coś nie spodoba ;d
Co do -1 na końcu tablicy to ma to być znak końca tablicy ale chyba nie ma zostać wpisany do samej tablicy tylko po prostu podczas wpisywania liczb jak ktoś wpisze -1 to kończy się wypełnianie tablicy.
Ale szczerze to już nie wiem totalnie w jakim kierunku iść. Spróbuję z tym co podałeś jak wrócę do domu, a jak nie będzie poprawne to spróbujemy z tym -1.

WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Niestety nie poradziłem sobie z dodaniem tego. Wyrzuca błąd [Error] invalid types 'const int[int]' for array subscript

Kopiuj
#include <stdio.h>
#define len(array) (sizeof((array))/sizeof((array)[0]))
int tab_size(const int* tab);
int main()
{
    int a[100];
    int *tab=&a[0];
    int i=0;
    int podana;
	int size=0;
    
    //wypelnienie tablicy
    for(i=0;i<100;i++)
    {   
    printf("Podaj %d liczbe calkowita: ",i);
    scanf("%d",&podana);
    if(podana==-1)
			{
		
			printf("koniec\n");
			break;
			}
			
			else
			{
    		*(tab+i)=podana;
			size++;
			}
         
    }

    //wyswietlanie
    printf("\n wyswietlanie: \n");
    for(i=0;i<size;i++)
    {
    printf("%d ", *(tab+i));
    }
    tab_size(tab);
}
// zliczenie ilosci elementow tablicy
int tab_size(const int* tab)
{
//	printf("\n \n \n%d",*(tab));
	printf("%u\n", len(*(tab));
	return 0;
}

Kurcze nie wiedziałem, że to zadanie takie problematyczne będzie :/

edytowany 1x, ostatnio: flowCRANE
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 8 godzin
  • Postów:4943
1

Tablica ma się kończyć na -1.


MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
4

Proste iterowanie póki nie znajdzie -1

Kopiuj
int tab_size(const int *tab)
{
     int offset = 0;
     while (*(tab + offset) != -1)
     {
          offset++;
     }
     return offset;
}

możliwe pułapki

  • wskaźnik pokazuje losowe miejsce nie tablicę => będzie wywrotka programu
  • tablica nie jest zakończona -1 => wywrotka programu, ewentualnie zwrócenie niepoprawnego rozmiaru jak w bloku danych programu za tablicą w losowej komórce pamięci znajdzie -1
  • przekroczenie zakresu liczb dodatnich (choć tu sobie rzutowaniem na uint można poradzić, a i wątpliwe jest, żeby profesor wprowadził 2147483647 liczb podczas sprawdzianu kodu ;])

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 3x, ostatnio: MasterBLB
enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:5 dni
  • Postów:1027
0
MasterBLB napisał(a):
Kopiuj
     while (*(tab + offset) != -1)

A co to za potwór? Od co najmniej 30 lat istnieje konstrukcja indeksująca tablicę, tab[offset].

MasterBLB
W treści zadania jest wyraźnie wspomniane, że ma być wykorzystana notacja wskaźnikowa. Fakt też faktem, dla mnie osobiście taki zapis jest czytelniejszy w kwestii tego, co naprawdę się dzieje.
enedil
Hmm, chyba nie jest ciężko zrobić mental shift, by intencje obu wersji były tak samo czytelne.
MasterBLB
To raczej jak z gustami blondynki, brunetki czy rude - ja jak używam wskaźnika to lubię jawny zapis pokazujący, że używam wskaźnika. Ktoś inny z kolei bardziej sobie będzie cenił zwięzłość zapisu indeksowego.
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Ok dzięki wielkie, działa :)

Jednak mam problem, bo kod sprawdza maszyna i z tego co widzę oczekuje od programu, że liczby zostaną wpisane razem w postaci "124 424 425 125 -1", a nie że każda osobno w scanf.
W jaki sposób przerobić ten kod żeby użytkownik mógł wypełnić tablicę na raz?

Kod który już działa dla wpisania wielu liczb osobno do tablicy:

Kopiuj
#include <stdio.h>
int tab_size(const int* tab);
int main()
{
    int a[100];
    int *tab=&a[0];
    int i=0;
    int podana;
    int size=0;
 
    //wypelnienie tablicy
    for(i=0;i<100;i++)
    {   
    printf("Podaj %d liczbe calkowita: ",i);
    scanf("%d",&podana);
    if(podana==-1)
            {
 			*(tab+i)=podana;
            
            break;
            }
 
            else
            {
            *(tab+i)=podana;
            size++;
            }
 
    }
 tab_size(tab);
}
// zliczenie ilosci elementow tablicy
int tab_size(const int *tab)
{
     int offset = 0;
     while (*(tab + offset) != -1)
     {
          offset++;
     }
     printf("\n%d",offset);
     return offset;
}

Treść zadania:

Dana jest tablica typu int (np: {16909060, 84281096, 151653132, -1}). Zakładając, że -1 jest znacznikiem końca tablicy (nie wartością), napisz program, który pobierze od użytkownika tablicę liczb całkowitych (nie więcej niż 100), a następnie policzy i wyświetli liczbę danych w tablicy (tutaj 3). Zliczanie elementów powinno odbywać się w funkcji tab_size, o następującym prototypie:

int tab_size(const int* tab);
Parametry:

tab - wskaźnik na tablicę typu int, dla której ma zostać wyznaczona liczba elementów.

Wartość zwrócona:

Funkcja zwróci liczbę elementów znajdujących się w przekazanej tablicy lub wartość -1 w przypadku przekazania do funkcji błędnych danych.

Przykładowe wejście:

Wpisuj wartosci calkowite
-240 -210 -900 -50 -580 -60 -980 -540 -10 -180 -1
Przykładowe wyjście:

10
Uwaga! Do poruszania się po tablicach używaj zmiennej wskaźnikowej.

edytowany 1x, ostatnio: flowCRANE
MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0
wiezaawieza napisał(a):

Jednak mam problem, bo kod sprawdza maszyna i z tego co widzę oczekuje od programu, że liczby zostaną wpisane razem w postaci "124 424 425 125 -1", a nie że każda osobno w scanf.

W treści zadania nie ma jasno postawionego wymogu że tak ma to wyglądać, ale jeśli się upierasz to inny użytkownik 4p niedawno zamieścił kod robiący to, czego potrzebujesz


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Jak mówiłem - kod jest sprawdzany maszynowo (wrzucam kod programu, a na stronie uczelni kod jest sprawdzany przez maszyne pod różnymi kątami).

Udało mi się pójść do przodu i pokonać kilka błędów, które wyrzucała maszyna (wyrzuca jeden błąd na przesłanie pliku więc idzie to powoli, bo trzeba poprawić błąd żeby wiedzieć o kolejnych...)

Teraz mam problem, bo maszyna pokazała że jak wywołamy tab_size(NULL) to będzie błąd więc muszę program zabezpieczyć przed tym.

Zrobiłem więc:

Kopiuj
     while (*(tab + offset) != -1 && *(tab + offset) != '\0')
     {
        offset++;
     }

i myślałem, że to załatwi problem. Jednak pojawił się kolejny...
Null z tego co czytałem jest równy 0. I jeśli w ciągu liczb ktoś poda "1 2 3 4 0 34 5 6 -1"
to nasza funkcja zliczająca elementy w tablicy będzie liczyć je tylko do zera. dalsze elementy nie zostaną policzone.

I się zastanawiam czy dobrze wymyśliłem to dodanie && *(tab + offset) != '\0' w while'u czy powinien to być osobny warunek gdzieś. Jesteście bardziej ogarnięci więc może ktoś mi powie jak zabezpieczyć to przed NULL ale żeby dalej zliczało zera i liczby po 0...

Kod programu aktualny:

Kopiuj
#include <stdio.h>
int tab_size(const int* tab);
int main()
{
    int a[100];
    int *tab=&a[0];
    int i=0;
    int podana;
    int size=0;
 
    //wypelnienie tablicy
    printf("Podaj liczby calkowite:");
    for(i=0;i<100;i++)
    {   
    scanf("%d",&podana);
    if(podana==-1)
            {
 			*(tab+i)=podana;

            
            break;
            }
 
            else
            {
            *(tab+i)=podana;
            size++;
            }

    }
 tab_size(tab);
 return 0;
}
// zliczenie ilosci elementow tablicy
int tab_size(const int *tab)
{
     int offset = 0;
     
     while (*(tab + offset) != -1 && *(tab + offset) != '\0')
     {
        offset++;
     }
     printf("\nWielkosc tablicy: %d",offset);
     return offset;
}
edytowany 2x, ostatnio: flowCRANE
MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
1

Ależ nie. Wystarczy, jak moją funkcję zmodyfikujesz tak:

Kopiuj
int tab_size(const int *tab)
{
     if (tab == nullptr)//nullptr zadziała dla C++11, jakby kompilator się o to rzucał zastąp go słowem NULL
     {
        return -1;//
     }

     int offset = 0; 
     while (*(tab + offset) != -1
     {
        offset++;
     }
     //printf("\nWielkosc tablicy: %d",offset); to nie tutaj - daj drukowanie size'a na zewnątrz
     return offset;
}

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB
enedil
A czytałeś co to za język? Bo otagowane jest jako C, nie C++.
MasterBLB
A czytałeś komentarz do linii z nullptr?
WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

Działa ale maszyna wyrzuca błąd:

Test został przerwany; Wszystkie operacje na tablicach powinny być wykonywane za pomocą wskaźników, a nie operatora []!

Wszędzie starałem się używać wskaźników do operacji na tablicach. Nie widzę żadnej operacji bez wskaźnika jeśli chodzi o tablice ;/
Najwyżej zgłoszę to wykładowcy ale może ktoś widzi jeszcze coś.
Dziękuję bardzo MasterBLB za pomoc. Jakbyś widział jeszcze gdzieś że można użyć wskaźnika na działaniu na tablicy to daj znać.

Kod programu:

Kopiuj
#include <stdio.h>
int tab_size(const int* tab);
int main()
{
    int a[100];
    int *tab=&a[0];
    int i=0;
    int podana;
    int size=0;
 
    //wypelnienie tablicy
    printf("Podaj liczby calkowite:");
    for(i=0;i<100;i++)
    {   
    scanf("%d",&podana);
    if(podana==-1)
            {
 			*(tab+i)=podana;

            
            break;
            }
 
            else
            {
            *(tab+i)=podana;
            size++;
            }

    }
 tab_size(tab);
 return 0;
}
// zliczenie ilosci elementow tablicy
int tab_size(const int *tab)
{
     if (tab == NULL)
     {
        return -1;
     }
 
     int offset = 0; 
     while (*(tab + offset) != -1)
     {
        offset++;
     }
    printf("\nWielkosc tablicy: %d",offset); 
     return offset;
}

Myślę, że to już ostatni błąd do przejścia :D

edytowany 1x, ostatnio: flowCRANE
flowCRANE
Wstawiaj kod w znaczniki kolorujące składnię – ```cpp przed kodem, a po kodzie samo ```
MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:2 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0

Jest jeszcze jedna operacja używająca [ ] - pobranie adresu tablicy:

Kopiuj
int *tab=&a[0];

zastąp int a[100] i powyższą linijkę następującym kodem:

Kopiuj
int *tab = new int[100];

EDIT:
A nie, źle jest,to nie C++. Zamiast new trzeba użyć malloc, ewentualnie jeśli sposób kq z posta niżej zadziała.
@wiezaawieza
Oto poprawna wersja z malloc

Kopiuj
#include <stdlib.h> //wymagane aby był malloc
int *tab = (int*) malloc(100 * sizeof(int));

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 3x, ostatnio: MasterBLB
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:2 dni
  • Lokalizacja:Szczecin
4

Nie używaj nagiego new i delete.

Kopiuj
int *tab=&a[0];

jest równoważne z

Kopiuj
int *tab=a;

WI
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Postów:76
0

@MasterBLB: Wystarczyło zmienić

Kopiuj
int *tab=&a[0];

na

Kopiuj
int *tab=a;

@kq miał rację. Zadanie zaliczone :) Mam jeszcze z 60 zadań do zrobienia więc pewnie nie raz jeszcze będę potrzebował pomocy ale jesteście super, że pomagacie słabszym i dajecie porady na przyszłość. Wielkie dzięki jeszcze raz!

Temat do zamknięcia :)

kq
Zapraszamy. Wbrew niektórym złośliwym opiniom bardzo chętnie pomagamy, gdzie pomoc oznacza pomoc a nie wykonanie zadania za kogoś ;​)
MasterBLB
@wiezaawieza: to jeszcze pyknij ptaszka i łapkę przy pomocnym poście ^^

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.