Funcja Void Max zwracajaca najwieksza liczbe w tab.

0

Witam! Mam taki problem jako że nie za bardzo wiem co i jak w tym C++
Mam do napisania program
Napisz program wprowadzając dane do tablicy liczb całkowitych,program ma zwrocić najwieksza parzysta liczbę sprosród liczb wprowadzonych do tablicy(funkcja Void Max)
Wie ktoś jak to powinno wyglądać?
Z góry Dziękuje
Pozdrawiam

0

Zauzmy, ze juz masz dane w tej tablicy, to funkcja tak powinna wygladac.

void max(int *tab)
{
  int i, max = tab[0];
  for(i = 1; i < rozmiar; i++) {                /* rozmiar to liczba elementow w tablicy */
          if(!(tab[i] & 0x1)) {
               if(tab[i] > max)    
                       max = tab[i];
          }
  }
}

w max masz ta liczbe ;)

0

#include <conio.h>
#include <iostream>
using namespace std;

void  max(int *wsk);

void main ()
{
  try
  {
	int n;
	cout<<"Z ilu elementow sklada sie tablica? : ";
	while(!(cin>>n))
	{
		cout<<"To nie jest liczba calkowita, jeszcze raz ";
		cin.sync();
		cin.clear();
	}

	int *tablica=new int[n];

	for(int i=0;i<n;i++)
	{
		cout<<"Podaj liczbe : ";
		while(!(cin>>tablica[i]))
		{
			cout<<"To nie jest liczba calkowita, jeszcze raz ";
			cin.sync();
			cin.clear();
		}
	}

	void (*ws)(int*);
	 ws=max;     
	 ws(tablica);
	delete [] tablica;

  }

  catch (std::bad_alloc){
	  cout<<"Blad allokacji pamieci ";	}
  
     _getch();
}
void  max(int *wsk)
{

	int max=*wsk;

	while(*wsk)
	{
		if((max <* wsk) && ((*wsk) % 2 ==0))
			max=*wsk;
		wsk++;
	}
	cout<<max;
}
0

Sid:
To się raczej sypnie ;] Chodzi mi o tą nieskończoną pętlę w procedurze max

0

jaką nieskończoną??? Sprawdź sobie, na pewno wszystko śmiga . Pętle while(*wsk) znam z Symfoni c++, wiec o błędzie nie ma mowy... A pętla mówi... dopóki wskaźnik nie będzie pokazywał na NULL...

0

Nie na NULL tylko na 0 (chociaż to w sumie to samo). Jaką masz pewność że za końcem tablicy będzie 0?

Testowałeś ten program u siebie? Mój g++ nie umożliwia zaincludowanie conio.h ;/

Wywaliłem conio.h, dodałem jedną linijkę (tablica[n] = 1000), oraz jedną poprawiłem, oto kod:

#include <iostream>
using namespace std;

void  max(int *wsk);

int main ()
{
  try
  {
        int n;
        cout<<"Z ilu elementow sklada sie tablica? : ";
        while(!(cin>>n))
        {
                cout<<"To nie jest liczba calkowita, jeszcze raz ";
                cin.sync();
                cin.clear();
        }

        int *tablica=new int[n];

        for(int i=0;i<n;i++)
        {
                cout<<"Podaj liczbe : ";
                while(!(cin>>tablica[i]))
                {
                        cout<<"To nie jest liczba calkowita, jeszcze raz ";
                        cin.sync();
                        cin.clear();
                }
        }

        tablica[n] = 1000;

        void (*ws)(int*);
         ws=max;
         ws(tablica);
        delete [] tablica;

  }

  catch (std::bad_alloc){
          cout<<"Blad allokacji pamieci ";        }
  
}
void  max(int *wsk)
{

        int max=*wsk;

        while(*wsk)
        {
                if((max <* wsk) && ((*wsk) % 2 ==0))
                        max=*wsk;
                wsk++;
        }
        cout<<max;
}

Przetestuj to u siebie na liczbach < 1000. Ta metoda z while (*wsk) { cośtam; wsk++} sprawdza się tylko jeśli wstawisz gdzieś 0 explicite (np masz łańcuch ASCIIZ).

0
tablica[n] = 1000;

WTF????
wcześniej allokowałeś dynamicnie pamięć a teraz tą samą tablicą alokujesz statycznie??? Nie rozumiem??? Przecież to sie mija z celem??? Poza tym, aby tak napisać

 tablica[n] = 1000;

n musiało by być zadeklarowane tak:

const int n=1000;

bez sensu!!!!
Może i przesadziłem z tymi wskaźnikami... ale to dla tego, że wcześniej nie rozumiałem ich w 100% i teraz wszędzie ich używam, bo chcę po prostu je znać w 100%.
właściwie to przesdziłem tylko z tą linijką:

void (*ws)(int*);
	 ws=max;     
	ws(tablica);

bo wystarczyło by

max(tablica);

ale i tak w algorytmie zadbałem o wszystko... więc myślę, że nie masz co tutaj poprawiać po mnie...
aaa

wile(*wsk)

kompilator jest na tyle mądry że:

wewnątrz funkcji mamy znów pętle while. Wykonuje się ona dotąd , dopóki znak wskazywany przez wskaźnik- czyli wsk* - jest różny od null, czyli znaku asci różnego od zera

Cytat z Symfoni c++. Chyba nie muszę Ci go tłumaczyć na język polski???

Tak w ogóle, chyba za bardzo nie jesteś zaznajomiony ze wskaźnikami????

0
Sid_ napisał(a)

Cytat z Symfoni c++. Chyba nie muszę Ci go tłumaczyć na język polski???

Tak w ogóle, chyba za bardzo nie jesteś zaznajomiony ze wskaźnikami????

Jedna symfonia wiosny nie czyni. A Ty lepiej czytaj ze zrozumieniem, moje kilkuletnie doswiadczenie wskazuje na to ze petla while(wsk*) w tym zadaniu nie ma racji bytu, wiec nie masz racji wez to sobie do serca i po prostu przyznaj sie do bledu jesli jeszcze go nie widzisz to dokladnie przeanalizuj zadanie.

0
Sid_ napisał(a)
tablica[n] = 1000;

WTF????

wcześniej allokowałeś dynamicnie pamięć a teraz tą samą tablicą alokujesz statycznie??? Nie rozumiem??? Przecież to sie mija z celem??? Poza tym, aby tak napisać

 tablica[n] = 1000;

n musiało by być zadeklarowane tak:

const int n=1000;

bez sensu!!!!

Hmmm...

donkey7 napisał(a)
        int n;
        cout<<"Z ilu elementow sklada sie tablica? : ";
        while(!(cin>>n))
        // ...
        int *tablica=new int[n];
        // ...
        tablica[n] = 1000;

Teraz przeproś kolegę... Przecież jest dynamicznie, odróżniasz deklarację tablicy od przypisania wartości do jej elementu? WTF tam jest, ale z innego powodu - to przypisanie to wyjście poza zakres tablicy.

Sid_ napisał(a)

Może i przesadziłem z tymi wskaźnikami... ale to dla tego, że wcześniej nie rozumiałem ich w 100%
...
Tak w ogóle, chyba za bardzo nie jesteś zaznajomiony ze wskaźnikami????

Powiedz to samo patrząc w lustro.

Sid_ napisał(a)

kompilator jest na tyle mądry że:

wewnątrz funkcji mamy znów pętle while. Wykonuje się ona dotąd , dopóki znak wskazywany przez wskaźnik- czyli wsk* - jest różny od null, czyli znaku asci różnego od zera

Cytat z Symfoni c++. Chyba nie muszę Ci go tłumaczyć na język polski???

Ty jesteś na tyle 'mądry', że:

  • nie umiesz czytać ze zrozumieniem;
  • masz napisane 'znak ASCII', int jest znakiem ASCII?
  • pętla wykonuje się póki nie trafi na 0, czyli potencjalnie póki nie wypieprzy programu.

Tak w ogóle to po cholerę łapać bad_alloc? Jeszcze jedno:

donkey7 napisał(a)

Nie na NULL tylko na 0 (chociaż to w sumie to samo). Jaką masz pewność że za końcem tablicy będzie 0?

W C NULL to zerowy wskaźnik, w C++ czyste zero, co do cytatu z symfonii to warto zauważyć, że jest tam 'małe' null - null char, znak ASCII o kodzie 0, '\0'.

0

Myslalem, ze sobie z reszta poradzisz i sie czegos nauczysz ale jak sa problemy z takim programem to wrzucam jednak kod ;)

#include <stdio.h>
#include <stdlib.h>

void max(int *tab, int size) {
        int max = tab[0];

        while(size) {
                if(!(tab[size] & 0x1)) {
                        if(tab[size] > max)
                                max = tab[size];
                }
                size--;
        }

        printf("najwieksza parzysta %d\n", max);
}

int main(int argc, char *argv[])
{
        int i, rozmiar, *tablica;

        if(argc != 2) {
                printf("\nUSAGE: %s <size>\n", argv[0]);
                return 0;
        }

        i = rozmiar = atoi(argv[1]);
        tablica = (int*)malloc(rozmiar * sizeof(int));

        while(i) {
                scanf("%d", &tablica[i]);
                i--;
        }

        max(tablica, rozmiar);

        free(tablica);

        return 0;
}
0

Co to za nowa moda żeby wszystko brać od tyłu?

Tak napisany program się może w piękny sposób wypieprzyć na free i dać niewłaściwy wynik na max, ze względu na wartość osobliwą w tab[0].

Ech, naprawdę nie rozumiem czemu kolejna osoba chce pchać operacje od tyłu i to jeszcze nie tam gdzie trzeba, wychodząc poza zakres...

0

Dzieki wszystkim za pomoc jednak nadal nie ma efektu,program nie dziala.....
Program ma zwracac spośród liczb wprowadzonych do tablicy(tablica liczb calkowityvh typu int) najwieksza parzysta liczbe
Chodzi chyba o to zeby program też sprawdzal czy wprowadzona to tablicy liczba jest parzysta czy nie jest,i zwracał największa liczbę parzystą wprowadzoną do tablicy(funkcja return)

0

Chodzi mi raczej o dynamiczna alokacje tablicy,i zeby program sprawdzal które sposród wprowadzonych liczb jest liczbą parzystą a która nie,ponieważ do tablicy bedzie można wpisywac liczby parziste i nieparzyste

0
deus. napisał(a)

Co to za nowa moda żeby wszystko brać od tyłu?

A co to za roznica w tym przypadku, maja byc w tablicy i tyle ?

deus. napisał(a)

Tak napisany program się może w piękny sposób wypieprzyć na free i dać niewłaściwy wynik na max, ze względu na wartość osobliwą w tab[0].

Chyba nikt nie bedzie tam liter wpisywal, a jak juz potrzebuje ktos dokladnego gotowca z obsluga wyjatkow, sygnalow i takich tam no to chyba sam sie musi pomeczyc, a nie oczekiwac ze ktos zrobi to za niego za darmo. tak ?

deus. napisał(a)

Ech, naprawdę nie rozumiem czemu kolejna osoba chce pchać operacje od tyłu i to jeszcze nie tam gdzie trzeba, wychodząc poza zakres...

Absolutnie nie ma mowy o wyjsciu poza zakres tablicy!! Tez mi sie tak wydawalo na poczatku ale jak dam w petlach rozmiar-1 to pominie 1 element ;)

edit// Po glebszym zastanowieniu doszedlem do wniosku, ze jednak musi byc
i = rozmiar = (atoi(argv[1])-1);
W zlym miejscu przy testowaniu dalem -1 i stad wlasnie taki kod wrzucilem. deus oczywiscie masz racje program przy malych liczbach sie nie wywali, ale mimo to zostaja nadpisane metadane regionu na stercie i przy wiekszych liczbach bedzie glibc detected ze wzgledu na free(); poniewaz zostanie nadpisany wskaznik na poprzedni element sterty(previous chunk).
Natomiast bez free() na koncu program by sie tak szybko nie wywalil ;)

0

Słuchaj chłopcze, zacznij myśleć co piszesz.

t0m_k napisał(a)

A co to za roznica w tym przypadku, maja byc w tablicy i tyle ?

M.in. taka, że przez to źle iterujesz, możesz wypieprzyć program, używasz wartości osobliwych... Jest to nieczytelne, idiotyczne i zwyczajnie wolne.

t0m_k napisał(a)

Chyba nikt nie bedzie tam liter wpisywal

Co mają do tego litery? Ty po prostu rozpieprzasz stertę w najlepsze.

t0m_k napisał(a)

Absolutnie nie ma mowy o wyjsciu poza zakres tablicy!! Tez mi sie tak wydawalo na poczatku ale jak dam w petlach rozmiar-1 to pominie 1 element ;)

OK, a co mi zrobisz jak Ci udowodnię? Umówmy się tak - jak udowodnię to przed kolejnym durnym postem douczysz się podastaw i zaczniesz myśleć przy pisaniu kodu, bo takimi gotowcami to więcej krzywdy niż pożytku ludziom przynosisz.

Dobra, czas na dowód, nie będę się [CIACH!] z czekaniem aż sam zrozumiesz.

        i = rozmiar = atoi(argv[1]);
        tablica = (int*)malloc(rozmiar * sizeof(int));

        while(i) {
                scanf("%d", &tablica[i]);
                i--;
        }

Alokujesz i-elementową tablicę. Następnie zaczynasz iterację póki i jest różne od zera. To pierwszy błąd - i-elementowa tablica posiada elementy od 0 do i-1, Ty zaś przy pierwszym przebiegu pętli odwołujesz się do i-tego elementu, o jeden za tablicą. W ten sposób niszczysz też strukturę sterty, co może się przyczynić do wysypania programu w momencie wywołania free. Dopiero po użyciu zmniejszasz i o jeden, czyli ostatni przebieg pętli, który zeruje i, wygląda tak - wczytanie do elementu tablica[1], i--, warunek pętli staje się fałszywy. Co z elementem tablica[0]? Ano, wartość osobliwa...

void max(int *tab, int size) {
        int max = tab[0];

        while(size) {
                if(!(tab[size] & 0x1)) {
                        if(tab[size] > max)
                                max = tab[size];
                }
                size--;
        }

Max przyjmuje wartość tab[0], wartość, której nigdy nie wczytałeś, osobliwą. Następnie iterujesz w podobny sposób jak wyżej, równie niewłaściwy...

0

No tak, zabrałem się za klepanie odpowiedzi to łaskawie pomyślałeś i post wyedytowałeś...

0

Nie wyedytowalem tylko dopisalem koncowke oraz 8 minut przed Twoim postem to zrobilem :D

Nie wyspany jestem i stad takie dziwne historie mi wychodza ;)

0
tablica[n] = 1000;

o qtwa... chyba byłem bardzo śpiący:)
A co do pętli i tak uważam że jest poprawna...

0
int znajdzParzysta(int *tab, int size) {
      int i;
      for (int i=0; i<size; ++i) {
           if ((tab[i]&1)==0) {
                break;
           }
      }
      return i;
}

void najwiekszaParzysta(int *tab, int size) {
       int index= znajdzParzysta(tab,size);
       if(index==size) {
             printf("Brak liczby parzystej w tablicy");
             return;
       }

       int max = tab[index];

       do {
             if (max<tab[index]) {
                 max = tab[index];
             }
             ++index; // następna liczba po ostatniej znalezionej parzystej
             index = znajdzParzysta(tab, size-index)+index;
       } while(index<size);
       printf("największa parzysta to: %d\n", max);
}
0
Sid_ napisał(a)

A co do pętli i tak uważam że jest poprawna...

Niektórzy uważają, że są Hitlerem/Napoleonem/koniem. Mam Ci udowodnić, że nie jest?

Konstrukcja while(*pointer) jest dla Ciebie za trudna, więc zajmimy się samym warunkiem. *pointer - dla uproszczenia użyjmy indeksowania - pointer[0]. Mamy więc while(pointer[0]). No dobra, ale liczby nie są typami logicznymi, taka konstrukcja to niejawna forma wyrażenia != 0 - otrzymujemy while(pointer[0] != 0). Nadal twierdzisz, że to jest poprawne?

Pętla wykonuje się póki pod wskaźnikiem nie znajduje się int o wartości 0, czyli może zostać przerwana już przy pierwszym elemencie. Może też wyjść daleko poza tablicę - nie ma gwarancji, że gdziekolwiek za tablicą na pozycji będącej wielokrotnością rozmiaru inta będzie coś, co potraktowane jako int ma wartość 0 - możesz pięknie wyłożyć program bo dojdziesz do miejsca, gdzie zwyczajnie nie ma już przydzielonej strony pamięci.

Trybisz czy mam narysować schemat?

@MarekR22, dlaczego tak to przekombinowałeś?

...i dlaczego wszyscy się uparli na bycie chaxorami? Po [CIACH!] & 1? Kod powinien jasno wyrażać o co chodzi, normalną definicją parzystości jest podzielność przez dwa, % 2 == 0. Kompilator i tak zrobi & 1 jeżeli uzna to za najszybsze rozwiązanie, nie bawcie się w pseudooptymalizacje.

0

Hmm... właściwie masz racje...
Program mi się nie wysypał ani razy, ale ta pętla była przy okazji C-stringów...
Wystarczyło by tam zastosować taką pętle
for(int i=0;i<n;i++,wsk++)
i przekazać do funkcji jeszcze jeden parametr (n)

0

#include <conio.h>
#include <iostream>
using namespace std;

void  max(int *wsk,int n);

void main ()
{
  try
  {
        int n;
        cout<<"Z ilu elementow sklada sie tablica? : ";
        while(!(cin>>n))
        {
                cout<<"To nie jest liczba calkowita, jeszcze raz ";
                cin.sync();
                cin.clear();
        }

        int *tablica=new int[n];

        for(int i=0;i<n;i++)
        {
                cout<<"Podaj liczbe : ";
                while(!(cin>>tablica[i]))
                {
                        cout<<"To nie jest liczba calkowita, jeszcze raz ";
                        cin.sync();
                        cin.clear();
                }
        }
  
        max(tablica,n);
        delete [] tablica;

  }

  catch (std::bad_alloc){
          cout<<"Blad allokacji pamieci ";        }
  
     _getch();
}
void  max(int *wsk,int n)
{
        int max=0,l=0;

       for(int i=0;i<n;i++,wsk++)
        {
                if((max < * wsk) && ((*wsk) % 2 ==0))
		{
                        max=*wsk;
			l++;
		}
        }

	if(l==0)
	    cout<<"Brak liczby parzystej";
	else
	    cout<<max;
}

coś w ten serek....

0

Jeszcze jedno pytanie - po cholerę zmienna i w max?

0

i??? czy l ???
"l" jest po to, żeby sprawdzić, czy wystąpiła jakaś parzysta... a "i" jest do obrotu pętli....

0

No dobra, ale nie wykorzystujesz i do indeksowania tablicy (co byłoby najlepszym rozwiązaniem), jedynie do liczenia, do czego możesz wykorzystać spokojnie zmienną reprezentującą rozmiar tablicy, tutaj akurat Wasze 'od tyłu' pasuje, tylko trzeba uważać 'w którą stronę' się dekrementuje.

0

 for(int i=0;i<n;i++)
  {
       if((max <  wsk[i]) && ((wsk[i]) % 2 ==0))
         {
               max=wsk[i];
                l++;
         }
  }

znaczy sie...?

0

Niezbyt bystrzy jesteście. Napisałem tablica[n] = 1000 specjalnie (nawet ślepy widzi że to wychodzi poza zakres), aby zmienić wartość znajdującą się za końcem tablicy, ponieważ algorytm sida polegał na fakcie, że za tablicą występuje wartość 0.

0
donkey7 napisał(a)

Napisałem tablica[n] = 1000 specjalnie (nawet ślepy widzi że to wychodzi poza zakres), aby zmienić wartość znajdującą się za końcem tablicy, ponieważ algorytm sida polegał na fakcie, że za tablicą występuje wartość 0.

A masz gwarancję, że tylko jeden int o wartości zerowej się tam trafi? Twoje 1000 może przejść niezauważone ;)

0

Ekhm, jaśniej - masz pewność, że za tym tysiącem już nic nie ma? Np. pointer albo jego fragment, ew. jakiś heap guard - 1000 to wręcz NULL (równie niepoprawny pointer), za mała wartość. Cały cyrk polegał na przypadku tego, że bufor był ostatnim blokiem na stercie, co zawsze się dziać nie musi - programy pod tym względem nie są w 100% deterministyczne.

0

Moim zamierzeniem było pokazanie że algorytm jest niepoprawny, jeśli tuż za tablicą znajdą się niezerowe parzyste wartości. Po wykazaniu tego błędu resztę błędów można już łatwo wywnioskować - np to że jeśli za tablicą znajdą się same wartości dodatnie parzyste to można wyjechać wskaźnikiem "za daleko".

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