Funkcja zliczająca ilość elementów tablicy

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

#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;
}
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.

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 :/

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.

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.

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.

1

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

#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.

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.

0

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

#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 :/

1

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

4

Proste iterowanie póki nie znajdzie -1

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 ;])
0
MasterBLB napisał(a):
     while (*(tab + offset) != -1)

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

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:

#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.

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

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:

     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:

#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;
}
1

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

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;
}
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:

#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

0

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

int *tab=&a[0];

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

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

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

Nie używaj nagiego new i delete.

int *tab=&a[0];

jest równoważne z

int *tab=a;
0

@MasterBLB: Wystarczyło zmienić

int *tab=&a[0];

na

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 :)

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