Wątek przeniesiony 2014-10-29 12:11 z C/C++ przez ŁF.

if nie działa

0

Witam!
Mam problem, otóż warunek IF spelnia się pomimo, że jego warunek nie jest spełniony. Proszę o pomoc, która wyjasni tę zagadkę :)

 

if (pi % i == 0 && pi ==4)
{
temp = 0;
}

Nawet, jeżeli pi jest równe 4 to i tak nie nadaje temp wartosci 0.

Tutaj jest cały kod:

 #include <stdio.h>
#include <stdlib.h>
 
int prime(int pi)
{
int temp, i;
temp = 1;
for (i = (pi / 2); i > 2; i--)
{
if (pi % i == 0 || pi == 4)
{
temp = 0;
}

return temp;
}
}
int main()
{
int n, cos;
scanf("%d", &n);
do
{
scanf("%d", &cos);
if (prime(cos))
{
puts("tak ");
}
else
{
puts("nie");
}
n--;
} while (n != 0);
system("PAUSE");
return 0;
}

Z góry dziękuję za pomoc!

2

Tragiczne formatowanie, czytać się tego nie da.

Poprawione:

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

int prime(int pi)
{
    int temp, i;
    temp = 1;
    for (i = (pi / 2); i > 2; i--) {
        if (pi % i == 0 || pi == 4) {
            temp = 0;
        }

        return temp;
    }
}
int main()
{
    int n, cos;
    scanf("%d", &n);
    do {
        scanf("%d", &cos);
        if (prime(cos)) {
            puts("tak ");
        } else {
            puts("nie");
        }
        n--;
    } while (n != 0);
    system("PAUSE");
    return 0;
}

Teraz oczywiste jest, że to nie if nie działa, tylko dla pi równego 4 w pętli od razu nie wchodzi warunek i > 2 (bo i == 2), więc masz UB, bo funkcja nie ma returna.

0

Tak, przepraszam za format - wysłałem to z laptopa na e-meila, no i w rezulatcie wyszło tak.

Program działał dobrze, tylko przy czwórce działał niepoprawnie.

Jeżeli napisałeś odpowiedź na moje pytanie, to będę czytał aż do skutku, ponieważ nie rozumiem o co chodzi :)

Dzieki serdeczne za odpowiedź

Dobra, zrozumiałem - nie wiem czy to przez zmęczenie czy przez głupotę :DD

0

W takim razie polecam http://format.krzaq.cc/ na przyszłość (albo clang-format jak masz lokalnie) ;)

Spójrz na poprawiony kod - szczególnie gdzie jest return, a gdzie go nie ma (pod funkcją na ten przykład). Do tego sprawdź warunek funkcji. Dla przypadku pi == 4, i jest na początku równe 2, więc pętla (a zatem także if) wykona się 0 (słownie: zero) razy, ponieważ i > 2 nigdy nie będzie spełnione. Więc to nie wina ifa, tylko złego warunku pętli.

0

Dzięki za kolejną odpowiedź :)

Jeżeli znalazłbyś jeszcze sekundkę czasu, to może wiesz dlaczego SPOJ nie akceptuje tego zadania:

#include <stdio.h>
#include <stdlib.h>
 
int prime(int pi)
{
    int temp, i;
    temp = 1;
    for (i = (pi / 2); i >= 2; i--) {
        if (pi % i == 0 || pi == 4 ) {
            temp = 0;
        }
 
        return temp;
    }
}
int main()
{
    int n, cos;
    scanf("%d", &n);
    do {
        scanf("%d", &cos);
        if (prime(cos)) {
            printf("TAK\n");
        } else {
            printf("NIE\n");
        }
        n--;
    } while (n != 0);
    system("PAUSE");
    return 0;
}
 
0

Po pierwsze, wciąż masz return w złym miejscu. Wynikiem tego jest niepoprawne oznaczenie np. 15 jako liczby pierwszej http://melpon.org/wandbox/permlink/N7qJWiWt9t0VdHuY

W ogóle ten temp jest zbędny, ale brak returna poza pętlą jest karygodny (zresztą widzisz warning kompilatora: prog.cc:15:1: warning: control may reach end of non-void function [-Wreturn-type])

1

Poza tym nie powinno przyjąć tego rozwiązania bez sita Eratostenesa.

0

Tak, po poprawce wyskoczył komunikat, że przekroczono czas oczekiwania - szkoda, wolałem samemu pogłówkować.

Sorry za głupie pytania, następnym razem postaram się posiedzieć dłużej nad problem, niż zawracać wam tyłek na forum :>

Życzę 0 błędów.

0

Nie wiem czy sito będzie dobrym rozwiązaniem pod względem wymagań pamięciowych.

Złoty Kot:

po pierwsze: nie sprawdzaj do pi/2 tylko do sqrt(pi) (ponieważ jeśli a*b == c to a <= sqrt(c)b <= sqrt(c))

po drugie: sprawdzaj od dołu. Statystycznie znacznie szybciej opuścisz pętlę sprawdzającą, sprawdzając czy liczba dzieli się przez dwa (w 50% przypadków po jednej iteracji), niż przez jakieś ogromne liczby.

0

OK, świetnie
ten przeszedł :

 
#include <stdio.h>
#include <math.h>
 
int prime(int pi)
{
    int temp, i;
    temp = 1;
    for (i = 2 ;i<=sqrt(pi); i++) 
	{
        if (pi % i == 0 || pi == 4 ) {
            temp = 0;
        }
    }
    if(pi==1)
    {
    	temp=1;
    }
     return temp;
}
int main()
{
    int n, cos;
    scanf("%d", &n);
    do {
        scanf("%d", &cos);
        if (prime(cos) && cos != 1) {
            printf("TAK\n");
        } else {
            printf("NIE\n");
        }
        n--;
    } while (n != 0);
    return 0;
}


Jeszcze raz wielkie dzięki :D

1

To teraz spróbuj poprawić wynik stosując sito. Btw: sqrt w warunku pętli to zły pomysł, jeśli kompilator tego nie zoptymalizuje.

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