Skocz do zawartości

Programowanie - co wybrać?


Recommended Posts

O coś takiego mi chodziło:)

Dzięki śliczne!!

Na wszystkie zadanka przyjdzie czas tylko niestety trzeba poczekać :)

Takie pytanko, czy to wszystko jak np poniżej:

  • \t - tab
  • \n - nowa linia
  • \r - powrót karetki
  • \" - cudzysłów
  • \' - apostrof
  • \\ - backslash
  • float - 4 bajty - max ok 6-7 liczb po przecinku (posiadają przyrostek F, lub f)
  • double - 8 bajtów - max ok 15 cyfr po przecinku (posiadają przyrostek D, lub d)

uczyć się na pamięć, czy częściowo przyjdzie samo a resztę będzie się dochodziło w momencie samego zapotrzebowania?

 

I tak mnie gnębi:

System.out.println('a' + 'A'); - wyrzuca wartość 162, czyli taki zapis przydziela wartości z ASCII? Po co, albo dlaczego? Czytałem wypowiedź tego autora kursu ale kompletnie nie wiem co znaczy "Następuje automatyczne dopasowanie typu i typ char jest zamieniany na typ int." :D Pojawia się hasło "int" o którym nie było mowy.

 

Jak jest różnica z oznaczeniami ''?

        System.out.println(1+2); ->Wynik 3:)

        System.out.println('1'+'2'); -> Wynik 99 ==WTF?

 

Jaka różnica? Efekt ten sam.

        System.out.println("Jakiś tekst i\nnowy wiersz\n\n");

        System.out.println("\r\rNowy wiersz i \nnowy wiersz");

Tzn w pierwszym 2wiersze wolne pod tekstem, w drugim nad tekstem i to jest jedyna różnica?

 

Jeśli pytam o coś głupiego, lub za bardzo wnikam, lub jest coś, co się pojawi za chwilę w następnych krokach proszę dać znać. Nie wiem czy nie za bardzo smaruje tymi pytaniami:)

 

I jeszcze jedno, czy w programowaniu Java kwestia stricte matematyki jest na porządku dziennym?

Edytowane przez qwert
Link to post
Share on other sites

Takie pytanko, czy to wszystko jak np poniżej:

  • \t - tab
  • \n - nowa linia
  • \r - powrót karetki
  • \" - cudzysłów
  • \' - apostrof
  • \\ - backslash
uczyć się na pamięć, czy częściowo przyjdzie samo a resztę będzie się dochodziło w momencie samego zapotrzebowania?

 

A dasz radę przez najbliższy rok zakuwać tysiące stron artykułów, blogów i książek, nie wiedząc, co się w ogóle przyda? Ja bym nie dał. Poza tym kucie to idealny sposób, by nie rozumieć, co się dzieje.

\ to znak ucieczki (i tyle możesz zakuć - nazwę). Powoduje on, że to, co jest po nim, zachowuje się inaczej, niż normalnie.

 

Taki kod:

System.out.println("nnn");
Wyświetla

nnn
bo każde z trzech n zachowuje się normalnie.

 

A taki:

System.out.println("n\nn");
Wyświetla

n
n
bo środkowe n stało się znakiem nowej lini z powodu poprzedzenia go znakiem ucieczki \.

 

A powiedzmy, że ktoś faktycznie chce wyświetlić

n\nn
Co teraz? \ jest znakiem ucieczki i wszystko nam psuje. No to trzeba go uciec, by przestał nim być i stał się zwykłym ukośnikiem. Więc:

System.out.println("n\\nn");
I działa. Pierwszy \ jest znakiem ucieczki dla drugiego \, który staje się zwykłym ukośnikiem.

 

Poza tym, uciekanie znaków też zależy od technologii. W HTML > oznacza zamknięcie tagu. Żeby mieć > jako zwykły znak, nie robi się \>, tylko >

 

Jak jest różnica z oznaczeniami ''?

        System.out.println(1+2); ->Wynik 3:)

        System.out.println('1'+'2'); -> Wynik 99 ==WTF?

Tutaj można by dużo pisać. Wchodzi w grę polimorfizm, niejawne konwersje typów danych, przeciążanie. Łatwiej by to było zrozumieć, wiedząc, co to są przeciążone metody i przeciążone operatory (tego akurat nie ma w Javie, tylko C++). Ale generalnie kompilator widząc coś takiego: 1+2, wie co zrobić. Ma dwie liczby, więc je doda. Widząc "a" + "b" też wie. Ma dwa napisy i jest ze sobą sklei (skonkatenuje w fachowej nomenklaturze). Widząc takie coś: "abc" + "123" też nie ma problemu, bo to nadal są dwa napisy i je skonkatenuje do "abc123".

Widząc "abc" + 123 sprawa ma się gorzej, bo nie dodaje się liczb z napisami. Co się stanie, zależy tak naprawdę od używanej technologii. Te bardziej restrykcyjne wywalą błąd i poproszą o własnoręczne przekonwertowanie jednego typu do drugiego, by się zgadzało. Te bardziej liberalne spróbują same niejawnie coś pozmieniać. Java sama zamieni liczbę 123 na napis "123" i w efekcie będzie "abc123".

Ty spróbowałeś dodawać dwa znaki '1' i '2', a co się stało, po części odpowiedziałeś sobie sam. Przed dodaniem znaki zostały zamienione na liczby. W ASCII '1' to 49, a '2' to 50. I stąd się wzięło 99.

Niejawne konwersje typów często powodują wiele durnych błędów, ciężkich do znalezienia. Co na co i kiedy się zmienia można zakuć. :P

Przykład: chcemy porównać dwie rzeczy:

"1e1"==10
Co się stanie? Zależy. Java nie pozwoli tego skompilować, informując, że typy są niezgodne i sama nie potrafi tego przekonwertować. JavaScript uzna, że "1e1, to wykładniczo zapisana liczba 10 i powie, że TAK, 10 jest równe 10.

 

  • float - 4 bajty - max ok 6-7 liczb po przecinku (posiadają przyrostek F, lub f)
  • double - 8 bajtów - max ok 15 cyfr po przecinku (posiadają przyrostek D, lub d)
Znowu konwersja typów danych. Dla Javy (i nie tylko) 2.4, 2.40, 1.0, -15.7364 to double. Typ dla liczb zmiennoprzecinkowych zachowujący dużą precyzję obliczeń. Konkretnie podwójną, stąd double. float to też typ dla liczb zmiennoprzecinkowych, ale oferujący mniejszą precyzję. Kod:

double zmienna = 2.75;
Tworzy zmienną typu double o nazwie zmienna i przypisuje jej wartość 2.75.

 

Kod:

float zmienna = 2.75;
powoduje błąd, bo Java sama nie umie niejawnie zamienić double na float. Trzeba jej pomóc:

float zmienna = 2.75f;
To f to nie jest jakiś przyrostek do zakucia, tylko jawna konwersja typu double do float. Celowo zmniejszasz precyzję. To samo można zrobić w ten sposób:

float zmienna = (float) 2.75;
Takie coś:

System.out.println(1.15f - 1.1f);
System.out.println(1.15 - 1.1);
wyświetli

0.049999952
0.04999999999999982
Jak widać na double poszło lepiej niż na float. Czyli się zgadza, że double oferuje większą precyzję. Ale oba wyniki niewiele mają wspólnego z rzeczywistością, bo nie wyszło 0.05. Wniosek? Ani float, ani double nie nadaje się do liczenia pieniędzy. Chyba, że ktoś lubi, gdy te znikają. :)

 

\r \n

Do stawiania nowej linii służy \n. \r to relikt przeszłości i jego używanie może powodwać problemy, mimo, że też wymaluje nową linię. We wspomnianej parę dni temu książce Clean Code jest o tym mowa: link.

 

int

to typ danych do zapisywania liczb całkowitych.

 

I jeszcze jedno, czy w programowaniu Java kwestia stricte matematyki jest na porządku dziennym?

Java, C++, PHP, ... to tylko narzędzie/technologia. Co będzie potrzebne zależy od tego, co będziesz pisał. Pisząc silnik graficzny 3D zapewne będzie masa macierzy, całek, itp. Pisząc sklep internetowy będzie ogarnianie cookies, sesji, http. Edytowane przez Karister
Link to post
Share on other sites

Wyczerpująco i o dziwo nawet jasno jak dla mnie :P

Wniosek:

Nie wykuwać :D

Oznaczenie \ - jaśniutkie:)

Stosujemy \n - tutaj tak jak w przypadku \r to rozumiem tylko zastanawiało mnie czy jedyna różnica to stworzenie pustego wiersza, także temat jasny już:)

Jeśli chodzi o kwestie 1,2,3,4 a '1', '2', '3', '4' - Z liczbami z klawiatury ok, natomiast co do 'znak' automatycznie zostanie przekonwertowane do wartości ASCII.

Trochę nie ogarniam float i double, bo generalnie po co konwertować? Czy nie można od razu korzystać z samego double czy float i się tego trzymać? Właśnie to jest bolączka, gdzie nie korzysta się z pełnego kursu tylko okrojonego, przygotowującego do pełnych podstaw;/ Nie do końca wiem jeszcze jak zapisać poprawnie kwestie np zmienna float, bo ogólnie Eclipse wyrzuca mi błąd z nazwą zmienna. Sam zapis System.out.println(1.15 - 1.1); od razu mówi, że jest to double, a tylko w przypadku float należy dodać f? Tak mi to wychodzi:) Chociaż w opisie wynika, że jest d lub D.

Tak samo z int, gdzie nie mam w tym opisanego gdzie dokładnie i jak trzeba wstawić to int, ale o tym też poszperam po necie.

Fajnie, żeby mieć takiego fachowca po sąsiedzku, trochę było by łatwiej:)

Dzięki po raz kolejny!!

Link to post
Share on other sites

Trochę nie ogarniam float i double, bo generalnie po co konwertować? Czy nie można od razu korzystać z samego double czy float i się tego trzymać?

double Ci w zupełności wystarczy do szczęścia. float są używane na przykład przy obliczaniu efektów cząsteczkowych przez kartę graficzną w grach. Karty graficzne są zaprojektowane tak, że efektywnie działają na typie float. Dodatkowo float zajmuje mniej pamięci, co pewnie też ma jakieś znaczenie. Generalnie dość specyficzny przypadek i nie mój klimat, by wiele tutaj napisać. Aplikacje webowe to inny świat. Używa się wolnych mechanizmów programowania, które za to pozwalają pisać elastyczny kod, który jest łatwy do zmieniania i ponownego używania. Braki w wydajności rekompensują komputery typu kilkanaście czterordzeniowych procesorów + kilkaset GB RAMu. :)

 

 

Jeśli chodzi o kwestie 1,2,3,4 a '1', '2', '3', '4' - Z liczbami z klawiatury ok, natomiast co do 'znak' automatycznie zostanie przekonwertowane do wartości ASCII.

Dla jasności - znak jest znakiem i nim zostanie. Konwersja następuje wtedy, gdy jest potrzebna i nie powoduje, że char (znak) staje się na stałe czymś innym. Taki kod:

char znak1 = 49;
char znak2 = '1';

System.out.println(znak1);
System.out.println(znak2);

System.out.println(znak1 + 1);
System.out.println(znak2 + 1);

System.out.println(znak1);
System.out.println(znak2);
wyświetli

1
1
50
50
1
1
Jak widać, znaki pozostały znakami mimo, że chwilę wcześniej były konwertowane.

 

Ponadto, nie jest zasadą, że char zawsze będzie konwertowany na int. Będzie konwertowany na to, co akurat potrzeba. Tutaj:

System.out.println('1' + "1");
Jest char i String (typ tekstowy). String jest ogólniejszy, więc char zostanie do niego skonwertowany. Zatem '1' przekształci się w "1" i całość da wyrażenie "1" + "1", czyli łączenie dwóch tekstów. Wynik to "11".

Jeśli się nie chce myśleć, co na co się niejawnie zamieni, można samemu zamienić na to, co potrzeba:

System.out.println(String.valueOf('1') + 1);
Tutaj wymuszamy zamianę char '1' na String "1". Całość ma teraz postać "1" + 1. Typy nadal się nie zgadzają, więc Java sama jeszcze zamieni int 1 na String "1". Czyli jest "1" + "1". Typy się teraz zgadzają, nastąpi konkatenacja napisów i wynik to "11". Można wszystko samemu pozamieniać, żeby Java sama nic nie robiła za plecami:

System.out.println(String.valueOf('1') + String.valueOf(1));
Tutaj sami zamieniamy Na String i char i int, dostając "1" + "1", czyli "11".

Zamiast zamieniać na String można też zamienić na coś innego, gdy trzeba. Na przykład na int:

System.out.println(Character.getNumericValue('1') + 1);
char zamieniamy na int i dostajemy 1 + 1 = 2.

 

Ogólna zasada jest taka, że gdy typy się nie zgadzają i nastąpi niejawna konwersja, to będzie ona do typu ogólniejszego. Przykłady:

2 + 1.0f // 2 zostanie zamienione na 2.0f (int na float).
2 + 1.0 // 2 na 2.0 (int na double).
2.0f + 1.0 // 2.0f na 2.0 (float na double).
To logiczne, że zamienia się na typ ogólniejszy, bo inaczej może dojść do utraty informacji. Na przykład możesz się uprzeć, że jednak chcesz odwrotnie: double na int:

System.out.println((int)2.5 + 2);
Wynik: 4, bo wymuszasz zamianę double na int, a int nie przechowuje informacji o części ułamkowej liczby. Tracisz więc 0.5.

 

 

Sam zapis System.out.println(1.15 - 1.1); od razu mówi, że jest to double, a tylko w przypadku float należy dodać f? Tak mi to wychodzi:) Chociaż w opisie wynika, że jest d lub D.

Nom. Liczby typu 1.00, 1.15, 16.7798 są w Javie domyślnie typu double, póki ktoś ich celowo nie zamieni na coś innego, np dopisując literkę f na końcu. Dopisanie d nic nie daje. Czy to 10.5, czy 10.5d, to i tak jest double. Niektórzy twierdzą, że dodanie d pozwala bez namysłu stwierdzić, że to double, co ułatwia czytanie kodu. Wg mnie bez sensu tak smarować d, gdzie nie trzeba. Natomiast 10, a 10d to już co innego. Pierwsze to int, a drugie double. 10.0 to też double. Przykłady:

System.out.println(1 / 10); // wynik 0 bez konwersji

System.out.println(1.0 / 10); // wynik 0.1, bo konwersja do 1.0 / 10.0
System.out.println(1 / 10.0); // wynik 0.1, bo konwersja do 1.0 / 10.0
System.out.println(1d / 10); // wynik 0.1, bo konwersja do 1.0 / 10.0
System.out.println(1 / 10d); // wynik 0.1, bo konwersja do 1.0 / 10.0

System.out.println(1.0 / 10.0); // wynik 0.1 bez konwersji
System.out.println(1d / 10d); // wynik 0.1 bez konwersji
System.out.println(1.0 / 10d); // wynik 0.1 bez konwersji
System.out.println(1.0d / 10d); // wynik 0.1 bez konwersji
Edytowane przez Karister
Link to post
Share on other sites

Nie wszystko ogarniam, ale muszę to zwyczajnie przećwiczyć, wtedy będzie troszkę jaśniej, albo przynajmniej wejdzie w krew:D

 

 

Jak widać, znaki pozostały znakami mimo, że chwilę wcześniej były konwertowane.

No właśnie, co jest przyczyną, że pozostają znakami?

Jeśli 1+'1'=50, to wyświetlenie samego '1' powinno dać 49;/ Trochę to dziwne...

Ogólnie to już zaczynają się schodki, a to początek początku;/

Najgorsze jest to, że wczoraj jak robiłem takie przypomnienie samemu to mam wrażenie że jak wymyślam coś sam dla siebie to wymyślam to w taki sposób, abym znał odpowiedź. Chociaż wydaje mi się że robię to i nie do końca świadomie i zwyczajnie z braku kompletnej wiedzy;/

 

 

Nom. Liczby typu 1.00, 1.15, 16.7798 są w Javie domyślnie typu double, póki ktoś ich celowo nie zamieni na coś innego, np dopisując literkę f na końcu.

Jak słoneczko:)

Link to post
Share on other sites

To może ze szczegółami po kolei:

 

Dla komputera wszystko jest liczbą. Więc trzeba jakichś umownych konwencji, kiedy która liczba co oznacza. Po to masz typy danych, by jako programista móc się *dogadać* z komputerem, że teraz pisząc 49 masz na myśli znak, a za chwilę kolor. Wtedy program *wie*, że 49 przypisane pod char to chodzi o naszą jedynkę, a 49 przypisane pod jakiś typ danych dla kolorów to nasz ciemny granatowy. A znowu przypisane pod int to po prostu chcemy zwykłą liczbę.

To tyle chcemy. By komp *ogarnął*, że liczba nie zawsze będzie reprezentować coś, co nią faktycznie jest.

Natomiast nie chcemy, by komputer to ze sobą zamieniał, gdy ma na to ochotę. Nie chcemy, by coś, co miało być kolorem nagle stało się liczbą.

Dlatego, jeśli już program faktycznie potrzebuje dokonać konwersji, robi to na boku, na jakieś kopii, by nie wysłać do niebytu tego, co sam sobie stworzyłem.

 

To:

char znak = '1';
System.out.println(znak + 1);
Można rozspiasać na:

char znak = '1';
int liczba = 1;
int znakZaminionyNaLiczbe = (int)znak;
int wynik = znakZaminionyNaLiczbe + liczba;
System.out.println(wynik);
Nie mogę dodawać znaku do liczby, więc wszystko musi być zamienione na ogólniejszy typ int. W drugim (dłuższym) kodzie ręcznie potworzyłem potrzebne zmienne, które pamiętają pokonwertowane dane. Ale jeśli zostawi się te konwersje na barkach Javy (krótszy kod), to kopie i tak zostaną gdzieś po cichu utworzone. Jak wcześniej pisałem, to jak wiele kompilator sam będzie próbował konwertować zależy od liberalności używanej technologii. Java ściśle pilnuje typów i na wiele sama sobie nie pozwala. Ale trochę jednak musi bo byłoby katorgą takie ręczne zamienianie każdej liczby, żeby je dodać, pomnożyć, itd.

Możesz się uprzeć, że powyższy wynik ma być typu char:

System.out.println((char)wynik);
Zostanie stworzona kopia zmiennej wynik, ta kopia przekonwertowana na char i tenże właśnie char będzie przekazany do funkcji System.out.println(...). A ta wymaluje wtedy 2.

 

Tyle o typach i konwersjach. Teraz o funkcjach (zwanych metodami w Javie).

 

Taki kod:

int liczba = 49;
char znak = '1';
System.out.println(liczba);
System.out.println(znak);
Gdzieś w dwóch miejscach RAMu zapisuje dwie liczby 49. Na jedno z tych miejsc RAMu wskazuje zmienna liczba (typu int) i na drugie wskazuje zmienna znak (typu char).

Wywołania funkcji System.out.println(...) w obu przypadkach wywołują inną funkcję. One mają tę samą nazwę, ale przyjmują argument o innym typie. Typ tego argumentu decyduje o tym, która z funkcji System.out.println(...) zostanie wywołana. A skoro to są dwie różne funkcje, to zapewne są inaczej zaprogramowane. Ta, co przyjmuje int, po prostu wyświetli faktyczną liczbę, a ta co przyjmuje char, wyświetli znak, któremu w tabeli ASCII odpowiada dana liczba. Tutaj: komputerowe 49 to nasze 1.

Mogłaby istnieć funkcja System.out.println(...), która przyjmowałaby typ colour (gdyby też istniał), a zaprogramowana by była tak, że na środku monitora wyświetlałaby piksel o danym kolorze.

Wtedy mogłoby być coś takiego:

colour kolor = /granatowy/;
int liczba = 49;
System.out.println(kolor);
System.out.println(liczba);
Obie te zmienne wskazują na obszary RAMu, gdzie zapisane są po prostu liczby 49. Ale wywołane zostałyby inne funkcje System.out.println(...). Pierwsza wymalowałaby na środku granatowy punkcik, a druga po prostu napisała 49.

 

Sam też możesz napisać takie funkcje o tej samej nazwie, co inaczej działają w zależności od typu parametru i nazywa się to przeciążaniem metod:

public class Main {
	
	public static void main(String[] args) {
		
		int liczbaCalkowita = 1;
		double liczbaZmiennoprzecinkowa = 1.5;
		
		mojaFunkcja(liczbaCalkowita);
		mojaFunkcja(liczbaZmiennoprzecinkowa);
		mojaFunkcja((int)liczbaZmiennoprzecinkowa);
	}
	
	private static void mojaFunkcja(int parametr) {
		System.out.println("liczby całkowite są nudne");
	}
	
	private static void mojaFunkcja(double parametr) {
		System.out.println("liczby zmiennoprzecinkowe są cool");
	}
}

Podsumowując, samo nic nie znika i nie zmienia się w coś innego, bo:

  • przed konwersją typu powstaje jego kopia
  • funkcje operują na kopii tego, co podawane jest jako ich parametr
Przy czym 2. jest prawdziwe dla typów prostych, jak int, double. Później poznasz typy obiektowe, które rządzą się innymi prawami.
Link to post
Share on other sites
  • 4 tygodnie później...
  • 2 tygodnie później...

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Odpowiedz w tym wątku...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...