Nowe posty

xx Problem ze sterownikami. (5)
2024-04-13, 21:25:16
xx Instalacja xfce4 (2)
2024-04-13, 16:20:17
xx Serie kompilacji bez instalacji dla “emerge” w Gentoo (2)
2024-04-08, 18:40:04
xx Plasma 6 w Neonie ssie trochę mniej ... (17)
2024-04-05, 10:03:46
xx Problem z Linux Lite po instalacji (3)
2024-04-03, 14:23:40
xx Jak właczyć num locka przy starcie systemu debian 12? (12)
2024-04-02, 17:43:54
xx Brak dźwieku w systemie. (5)
2024-04-02, 16:13:41
xx Dystrybucja pod HP Omen (7)
2024-03-29, 11:33:05
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
xx Ile pingwinów? (1)
2024-03-27, 08:59:24

Autor Wątek: unsigned, uproszczenie warunku  (Przeczytany 10152 razy)

Earth

  • Gość
unsigned, uproszczenie warunku
« dnia: 2007-09-13, 19:20:17 »
Gdy zaincjalizuje liczbę unsigned wprowadzę ujemną przez "cin" i poproszę o nią ponownie "cout" to wyświetli mi się jakaś długa liczba na minusie :( Czy używanie unsigned jest przydatne, a może to coś komplikator ma nie tak ustawione?

Mam wyrażenie if(1 < n1 and n1 < 1000 and 1 < k1 and k1 < 1000 and 1 < n2 and n2 < 1000 and 1 < k2 and k2 < 1000) czy nie da się tego jakoś skrócić? Próbowałem na różne sposoby, ale efektu nie było :(

chmooreck

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #1 dnia: 2007-09-13, 21:51:23 »
Cytat: Earth
Gdy zaincjalizuje liczbę unsigned wprowadzę ujemną przez "cin" i poproszę o nią ponownie "cout" to wyświetli mi się jakaś długa liczba na minusie :( Czy używanie unsigned jest przydatne, a może to coś komplikator ma nie tak ustawione?
może lepiej wklej kawałek kodu, powiedz co robi i powiedz jakich rezultatów byś oczekiwał...

Cytat: Earth
Mam wyrażenie if(1 < n1 and n1 < 1000 and 1 < k1 and k1 < 1000 and 1 < n2 and n2 < 1000 and 1 < k2 and k2 < 1000) czy nie da się tego jakoś skrócić?
nie da się

P.S. cin i cout są wygodne, ale wolne
P.S. 2 kompilator, a nie komplikator ;-) zwykle największym komplikatorem jest człowiek...

Earth

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #2 dnia: 2007-09-13, 22:42:23 »
Czyli lepiej używać scanf itp z daje się z cstudio(z C)? (Nie pamiętam dokładnie nazw. Nigdy nie używałem :)

ZipoKing

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #3 dnia: 2007-09-13, 22:57:33 »
Twój problem polega na tym, że próbujesz do zmiennej typu unsigned int, czyli liczby bez znaku (liczby dodatniej) wpisać liczbę ujemną, czyli coś, czego nie powinno tam być. Poczytaj o tym, jak zapisywane są liczby ujemne w pamięci komputera (klik) i pewnie znajdziesz odpowiedź.
Co zaś się tyczy if-ów, poleciłbym użyć nawiasów - jak się nie da tego skrócić, to chociaż można zrobić, żeby ładniej wyglądało ;)

chmooreck

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #4 dnia: 2007-09-13, 23:07:59 »
Cytat: Earth
Czyli lepiej używać scanf itp z daje się z cstudio(z C)? (Nie pamiętam dokładnie nazw. Nigdy nie używałem :)
Zależy... jak pobierasz 2 liczby od użytkownika to nie ma to znaczenia... jeśli masz do odczytania dużo danych - może stać się elementem kluczowym

Może być scanf... albo fgets i własna interpretacja


Poza tym dane do programu zwykle przekazuje się jako argumenty wywołania - łatwiej taki program zastosować w skryptach, ale to już oczywiście zależy od konkretnego przypadku

xis

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #5 dnia: 2007-09-14, 07:37:12 »
IF'a da się skrócić - możesz napisać f-cję
bool between( a, i1, i2 )
, która sprawdzi, czy wartość liczby a jest między i1 i i2 i zwróci odpowiedź - wtedy Twój if może wyglądać tak
if( between( n1, 1, 1000 ) 
 && between( n2, 1, 1000 )
 && between( k2, 1, 1000 )
 && between( k1, 1, 1000 ) )
Chociaż.. to chyba wcale nie jest krócej :P

Możesz więc napisać
 bool multibetween( a1, a2, a3, a4, i1, i2 )
sprawdzającą czy wszystkie a1, a2, a3 i a4 są w zakresie - taka brzydka f-cja służąca do jednej tylko rzeczy :)

ZipoKing

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #6 dnia: 2007-09-14, 11:17:12 »
A żeby było jeszcze dziwniej można wykorzystać magię języka C, wyrażenie:
if(a > 1 && a < 1000)
można zastąpić takim cudem:
#define between(a) ((unsigned)((a)-2)<998)
i wtedy twój if może wyglądać po prostu tak:
if(between(x1) && between(x2) && between(n1) && between(n2))
Jeżeli z kolei fanatycznie zależy ci na tym, aby program działał szybciej, w if-ie poukładaj warunki tak, aby zmienna, dla której najbardziej prawdopodobne jest, że nie spełni tego warunku, była na początku.

Earth

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #7 dnia: 2007-09-15, 16:29:07 »
Kod wygląda tak i służy tylko do nauki.
#include 

int main()
{
  unsigned short n1,k1,n2,k2;
  scanf("%d %d %d %d",&n1, &k1, &n2 ,&k2);
  if (1 < n1 and n1 < 1000 and 1 < k1 and k1 < 1000
      and 1 < n2 and n2 < 1000 and 1 < k2 and k2 < 1000) {
    printf("%d",(n1*k1)+(n2*k2));
  }
  return 0;
}
Po zmianach na print coś szwankuje:
earth@earth:~$ '/home/earth/Desktop/inf/sam/a.out' 
2 2 2 2
Segmentation fault (core dumped)
W której bibliotece znajdę funkcje multibetween i between?

ZipoKing

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #8 dnia: 2007-09-15, 17:28:25 »
Taki błąd ma prawo i obowiązek się pokazywać, a dlaczego?
Program nie wywala się na printf, ale na scanf. W scanf zadeklarowałeś, że prosisz o podanie zmiennej typu int (%d, w architekturze x86 4 bajty na zmienną), a podajesz wskaźnik do zmiennej typu short int (%h, 2 bajty na zmienną). scanf próbuje więc zapisać liczbę, którą poda użytkownik w 4 bajtach i nie wie o tym, że tych bajtów do dyspozycji są tylko 2, przez co występuje tzw. błąd przepełnienia stosu (można wręcz powiedzieć, że to podręcznikowy przykład z książki dla h4ck0rów ;)). W printf ten błąd nie występuje, bo tu już nie ma wskaźników i funkcja wiedząc z jakimi typami ma do czynienia potrafi sobie zrzutować short int na int.
Więcej info: man scanf.
Poza tym polecam zmienić #include na #include bo to żaden program w C++ ale najzwyklejsze C.

Earth

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #9 dnia: 2007-09-16, 14:57:41 »
Użyłem %hd i jet ok. A gdzie znajdę funkcję between?

ZipoKing

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #10 dnia: 2007-09-16, 15:18:43 »
Cytat: Earth
Użyłem %hd i jet ok. A gdzie znajdę funkcję between?
Funkcji between nie ma - możesz sam ją naskrobać ;-) - w powyższych postach znajdzesz m.in. wybryk w postaci mojego pomysłu :)

Earth

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #11 dnia: 2007-09-16, 15:40:34 »
A spoko, wydaje mi się że zastosowanie makra w tym wypadku zmniejszy wydajność, ale to już teraz nie istotne dla mnie. Więcej pytań nie mam co do tego tematu, dziękuje wszystkim za pomoc.

//Czy w przypadku plików też warto używać stdio.h? Pytanie się nie wiąże z tematem, więc utworzyłem nowy:
http://forum.linux.pl/viewtopic.php?pid=70247#p70247

chmooreck

  • Gość
unsigned, uproszczenie warunku
« Odpowiedź #12 dnia: 2007-09-16, 19:47:13 »
Cytat: Earth
A spoko, wydaje mi się że zastosowanie makra w tym wypadku zmniejszy wydajność
akurat zastosowanie makra nie będzie miało żadnego wpływu na wydajność, zawartość makra jest wpisywana w odpowiednie miejsce kodu przez preprocesor, czyli jeszcze przed kompilacją kodu. Inaczej rzecz się ma jeśli zastosować funkcję zamiast makra - pojawi się wtedy narzut potrzebny na jej wywołanie... ale i to niekoniecznie: jest całkiem prawdopodobne, że kompilator (uruchomiony z odpowiednimi opcjami) ten kawałek zoptymalizuje i efekt będzie dokładnie taki sam ;-)