Nowe posty

xx zapis klatki filmu mp4 w postaci obrazu jpg (2)
2019-09-16, 22:33:32
xx Dystrybucja do szkolnej pracowni. (6)
2019-09-16, 18:39:04
xx Jaką dystrybucje polecacie pod mój sprzęt? (1)
2019-09-16, 14:53:22
xx Thunderbird - jedna poczta na dwóch dystrybucjach (3)
2019-09-16, 12:34:56
xx Nowe forum linuxowskie (5)
2019-09-16, 11:55:40
xx zrobmikompa.pl - co myślicie o tej stronce (8)
2019-09-16, 11:44:47
xx Jaka dystrybucja pod mon sprzęt? (1)
2019-09-16, 10:52:58
xx BIOS nie widzi dysku z Linuxem (2)
2019-09-14, 10:41:31
xx Problem z antiX wersja live (0)
2019-09-12, 20:56:49
xx Serwer do Nauki (5)
2019-09-05, 07:35:50

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

Offline Grzegorz Ziemski

  • Users
  • Stały bywalec
  • ***
  • Wiadomości: 116
    • Zobacz profil
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 :(

Offline Piotr Chmura

  • Administrator
  • Guru
  • *****
  • Wiadomości: 5060
    • Zobacz profil
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...

Offline Grzegorz Ziemski

  • Users
  • Stały bywalec
  • ***
  • Wiadomości: 116
    • Zobacz profil
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 :)

Offline Paweł Smoliński

  • Administrator
  • Guru
  • *****
  • Wiadomości: 593
    • Zobacz profil
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 ;)
Gutta cavat lapidem non vi, sed saepe cadendo / sic homo doctus fit non vi sed saepe studendo

Offline Piotr Chmura

  • Administrator
  • Guru
  • *****
  • Wiadomości: 5060
    • Zobacz profil
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

Offline xis

  • Global Moderator
  • Guru
  • *****
  • Wiadomości: 1049
    • Zobacz profil
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 :)
Everything should be made as simple as possible, but not simpler
-- Albert Einstein

Offline Paweł Smoliński

  • Administrator
  • Guru
  • *****
  • Wiadomości: 593
    • Zobacz profil
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.
Gutta cavat lapidem non vi, sed saepe cadendo / sic homo doctus fit non vi sed saepe studendo

Offline Grzegorz Ziemski

  • Users
  • Stały bywalec
  • ***
  • Wiadomości: 116
    • Zobacz profil
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?

Offline Paweł Smoliński

  • Administrator
  • Guru
  • *****
  • Wiadomości: 593
    • Zobacz profil
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.
Gutta cavat lapidem non vi, sed saepe cadendo / sic homo doctus fit non vi sed saepe studendo

Offline Grzegorz Ziemski

  • Users
  • Stały bywalec
  • ***
  • Wiadomości: 116
    • Zobacz profil
unsigned, uproszczenie warunku
« Odpowiedź #9 dnia: 2007-09-16, 14:57:41 »
Użyłem %hd i jet ok. A gdzie znajdę funkcję between?

Offline Paweł Smoliński

  • Administrator
  • Guru
  • *****
  • Wiadomości: 593
    • Zobacz profil
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 :)
Gutta cavat lapidem non vi, sed saepe cadendo / sic homo doctus fit non vi sed saepe studendo

Offline Grzegorz Ziemski

  • Users
  • Stały bywalec
  • ***
  • Wiadomości: 116
    • Zobacz profil
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

Offline Piotr Chmura

  • Administrator
  • Guru
  • *****
  • Wiadomości: 5060
    • Zobacz profil
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 ;-)