Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]inkrementacja i dekrementacja zmiennej typu string
qpanas
post 12.05.2008, 21:28:24
Post #1





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Rozpocząłem niedawno naukę programowania w PHP i napotkałem problem, którego rozwiązania nie zdołałem znaleźć w żadnym posiadanym podręczniku ani znanym mi kursie internetowym. Wyjaśniam w czym rzecz.
Ćwiczyłem stosowanie operatorów na zmiennych. Kiedy doszedłem do etapu inkrementacji i dekrementacji napisałem sobie taki mały kawałek kodu:
  1. <?php
  2. $_a = "z";
  3. echo('1) zmienna typu '.gettype($_a).': '.$_a."
  4. ");
  5.  
  6. $_a = ++$_a;
  7. echo('2) zmienna typu '.gettype($_a).': '.$_a."
  8. ");
  9.  
  10. $_b = $_a++;
  11. echo('3) zmienna typu '.gettype($_b).': '.$_b."
  12. ");
  13. echo('4) zmienna typu '.gettype($_a).': '.$_a."
  14. ");
  15. $_a = --$_a;
  16. echo('5) zmienna typu '.gettype($_a).': '.$_a."
  17. ");
  18.  
  19. $_b = $_a--;
  20. echo('6) zmienna typu '.gettype($_b).': '.$_b."
  21. ");
  22. echo('7) zmienna typu '.gettype($_a).': '.$_a."
  23. ");
  24.  
  25. ?>

Jako wartość zmiennej $_a wstawiałem początkowo liczby i wszystko ładnie działało, ale potem dla testu wstawiłem literę i okazało się, że nie działa dekrementacja tej wartości string. Oto co wyświetla się w przeglądarce:
Cytat
1) zmienna typu string: z
2) zmienna typu string: aa
3) zmienna typu string: aa
4) zmienna typu string: ab
5) zmienna typu string: ab
6) zmienna typu string: ab
7) zmienna typu string: ab

Zacząłem szukać odpowiedzi dlaczego i okazało się, że we wszystkich przykładach operacje są wykonywane wyłącznie na liczbach. Znajomy znajomego stwierdził coś takiego:
Cytat
 trzeba by się wczytać, jak interpretuje php wartość 1 dla ciągu string - może to być kod znaku, albo jego index w tablicy znaków. ++ dodaje kolejny znak, -- nie odejmuje, bo wypada wartość mniejsza od 0 (a ma wartość 0 w tablicy znaków, -1 to nie ma znaku - więc się nie zmienia)
++ i -- nie wykonuje działań w zakresie liczb dodatnich, tylko całkowitych - więc 0 - 1 daje -1, a żaden znak nie ma takiego indeksu
oczywiście, przy założeniu, że a ma indeks 0 ale wątpię, żeby ktoś się zastanawiał, aby na stringach odpowiednio jakieś operacje arytmetyczne przebiegały - skoro nie ma żadnej dokumentacji ...

Sam nie wiem co o tym sądzić. Poza tym jeśli inkrementacja i dekrementacja służą do wykonywania operacji na liczbach, dlaczego inkrementacja działa na literach (zmiennych string). A jeśli można inkrementować literę to czemu niemożliwa jest jej dekrementacja? Błąd w samym php? Nie wierzę w to!

Ten post edytował qpanas 13.05.2008, 21:47:49
Go to the top of the page
+Quote Post
netmare
post 12.05.2008, 21:30:26
Post #2





Grupa: Zarejestrowani
Postów: 285
Pomógł: 37
Dołączył: 18.12.2007
Skąd: Łódź

Ostrzeżenie: (0%)
-----


a jaki wynik wg. Ciebie powinna mieć inkrementacja ciągu abc?
Go to the top of the page
+Quote Post
qpanas
post 12.05.2008, 21:38:28
Post #3





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Cytat(netmare @ 12.05.2008, 21:30:26 ) *
a jaki wynik wg. Ciebie powinna mieć inkrementacja ciągu abc?

Nie wiem jaki powinna mieć, ale ma abd
Cytat
1) zmienna typu string: abc
2) zmienna typu string: abd
3) zmienna typu string: abd
4) zmienna typu string: abe
5) zmienna typu string: abe
6) zmienna typu string: abe
7) zmienna typu string: abe

Problem w tym, że skrypt nie dekrementuje tego ciągu. Uczę się i chcę wiedzieć dlaczego coś działa lub nie, a nie tylko, jak pies Pawłowa, reagować na żarówkę tzn. wstaw to i to i będzie ok, a czemu to już sobie biednej główki nie kłopocz dziecię.

Ten post edytował qpanas 13.05.2008, 21:48:27
Go to the top of the page
+Quote Post
netmare
post 12.05.2008, 21:41:16
Post #4





Grupa: Zarejestrowani
Postów: 285
Pomógł: 37
Dołączył: 18.12.2007
Skąd: Łódź

Ostrzeżenie: (0%)
-----


no bo żeby coś działało to najpierw ktoś by musiał ustalić jaki ma dać rezultat, a z matematycznego punktu widzenia ciężko wykonać 'abc' + 1, przynajmniej w matematyce której uczyli dzieci jak ja tongue.gif
Go to the top of the page
+Quote Post
qpanas
post 12.05.2008, 21:45:56
Post #5





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Mnie też uczyli matematyki, ale także dociekliwości. Skoro taka operacja z matematycznego punktu widzenia jest nieprawidłowa, dlaczego jest wykonywana i to do tego prawidłowo, bo "dodanie 1" w tym przypadku jest podniesieniem o jedną pozycję w alfabecie. Natomiast skoro inkrementacja wykonywana jest "prawidłowo", dlaczego takiego samego efektu nie przynosi dekrementacja.
Go to the top of the page
+Quote Post
netmare
post 12.05.2008, 21:55:49
Post #6





Grupa: Zarejestrowani
Postów: 285
Pomógł: 37
Dołączył: 18.12.2007
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Nawet mi się nie chce myśleć dlaczego i jaki wynik da inkrementacja z + 1 i dlaczego akurat taki, a nie inny. Na Twoim miejscu skorzystał bym z tego że do ciągu możesz się odwołać jak do tablicy, z funkcji strlen, chr i ord i zrobił własną inkrementację/dekrementację zamiast polegać na matematycznych zapisach w przypadku stringu winksmiley.jpg poza tym obawiam się że przy zapisie np a1b2 rezultaty inkrementacji o 1 mogą być wręcz niesamowite w porównaniu z efektem którego się spodziewasz winksmiley.jpg
Go to the top of the page
+Quote Post
Kicok
post 12.05.2008, 22:02:46
Post #7





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

Ostrzeżenie: (0%)
-----


Cytat
PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in Perl 'Z'+1 turns into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported.



http://www.php.net/manual/en/language.oper...s.increment.php

Ten post edytował Kicok 12.05.2008, 22:03:11


--------------------
"Sumienie mam czyste, bo nieużywane."
Go to the top of the page
+Quote Post
qpanas
post 12.05.2008, 22:08:41
Post #8





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Zgodnie z sugestią sprawdziłem wynik inkrementacji a1b2 i oto co wychodzi:
Cytat
1) zmienna typu string: a1b2
2) zmienna typu string: a1b3
3) zmienna typu string: a1b3
4) zmienna typu string: a1b4
5) zmienna typu string: a1b4
6) zmienna typu string: a1b4
7) zmienna typu string: a1b4

Czyli wynik jest prawidłowy dla inkrementacji ale nadal bez efektu przy dekrementacji. Natomiast z uporem maniaka drążę temat, ponieważ jeśli cała sprawa jest wynikiem jakiegoś wewnętrznego błędu samego PHP to nasuwa się inne pytanie - czy to jest źródło potencjalnego zagrożenia. Zaczynam przygodę z PHP i programowaniem i nie mam pojęcia niemal o niczym, a szczególnie o zagadnieniach bezpieczeństwa, ale jako użytkownik Linuksa jestem na tym punkcie wręcz przeczulony. Poza tym już taki jestem, że lubię wiedzieć "co jest w środku". Nadal więc czekam na Mistrza i chwilę oświecenia ;-)

P.S. Właśnie zauważyłem, że w trakcie pisania tego posta pojawiła się odpowiedź Kicoka. Muszę przez nią przebrnąć ze słownikiem w ręku i wtedy pewnie będę mądrzejszy o kolejną informację. Dzięki Kicok

Ten post edytował qpanas 13.05.2008, 21:48:51
Go to the top of the page
+Quote Post
netmare
post 12.05.2008, 22:19:02
Post #9





Grupa: Zarejestrowani
Postów: 285
Pomógł: 37
Dołączył: 18.12.2007
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Kicok, już wyklarował sprawę odpowiednim cytatem winksmiley.jpg
A ja się faktycznie pomyliłem winksmiley.jpg

'a1b2'+1 da wynik 1

a co do błędu to raczej go nie ma winksmiley.jpg
Go to the top of the page
+Quote Post
qpanas
post 12.05.2008, 22:26:35
Post #10





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Mylić się rzecz ludzka :-) Ja zaś jestem jak dziecko we mgle. Bez kompasu czyli znajomości angielskiego ciężko znaleźć odpowiedź na nurtujące pytania. Life is brutal ;-)
Go to the top of the page
+Quote Post
dr_bonzo
post 12.05.2008, 22:48:29
Post #11





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


qpanas: niesmiertelne RTFM biggrin.gif, ale chyba nie musze ci przypominac.

Cytat
Poza tym jeśli inkrementacja i dekrementacja służą do wykonywania operacji na liczbach, dlaczego inkrementacja działa na literach (zmiennych string). A jeśli można inkrementować literę to czemu niemożliwa jest jej dekrementacja? Błąd w samym php? Nie wierzę w to!

++/-- to tylko operator, to co robi na zmiennej zalezy od tego jak jezyk programowania jest zrobiony.
Szczegolnie ze w C++ masz przeciazanie operatorow i mozesz z nimi robic rozne niebezpieczne rzeczy ]snitch.gif


-------
PL:

PHP zachowuje sie jak perl, a nie jak C w operacjach arytmetycznych na zmiennych znakowych (w php tylko stringi).
W Perlu 'Z'+1 ==> 'AA', gdzie w C 'Z'+1 ==> '[' ( ord('Z') == 90, ord('[') == 91 ).
[No i], dziala tylko inkrementacja, i tylko na znakach ASCII [a-zA-Z].

Ten post edytował dr_bonzo 12.05.2008, 22:56:22


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Pilsener
post 13.05.2008, 07:43:35
Post #12





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Miałem podobny problem, pisząc funkcje do obsługi plików .xls, gdzie kolumny masz a,b,c.. ad, de itp. winksmiley.jpg
Łatwo sobie z tym poradzić używając range(). Oto przykład użycia, funkcja, która zamienia numer kolumny na odpowiednią literę alfabetu:
  1. <?php
  2. function excel_kolumna($nr_kol){ //zamienia numer kolumny na oznaczenie alfabetyczne
  3.  $literki = range('a','z'); 
  4.  $ile_literek = count($literki);
  5.  $ile_p = floor(($nr_kol-1)/$ile_literek);
  6.  $pierwsza_l = $literki[$ile_p-1];
  7.  $druga_l = $nr_kol-($ile_p*$ile_literek)-1;
  8.  $druga_l = $literki[$druga_l];
  9.  $literka = $pierwsza_l.$druga_l;
  10.  return $literka;
  11. }
  12. ?>
- nie jest to może szczyt profesjonalizmu, ale działa smile.gif
Go to the top of the page
+Quote Post
qpanas
post 13.05.2008, 18:50:46
Post #13





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


dr_bonzo dzięki za tłumaczenie z angielskiego, a o RTFM oczywiście nie musisz mi przypominać. Zresztą już w poście otwierającym ten wątek pisałem, że przeszukałem podręczniki i znane mi kursy PHP - niestety tylko te po polsku, bo anglojęzyczne materiały są dla mnie niedostępne (mea culpa).
Pilsener - potestuję sobie tę funkcję - dzięki za podpowiedź. Długa droga przede mną. Gdyby tak mieć nauczyciela, który pokaże, powie co i jak i odpowie na nurtujące pytania. Niełatwo być samoukiem ;-) Pozdrawiam wszystkich phpowych wymiataczy ;-)
Go to the top of the page
+Quote Post
Piniek
post 13.05.2008, 19:13:25
Post #14





Grupa: Przyjaciele php.pl
Postów: 463
Pomógł: 49
Dołączył: 27.12.2007
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Przenoszę na przedszkole, proszę o dodanie tagu do tematu i poprawienie bbcode.


--------------------
Go to the top of the page
+Quote Post
qpanas
post 13.05.2008, 21:49:38
Post #15





Grupa: Zarejestrowani
Postów: 30
Pomógł: 2
Dołączył: 12.05.2008

Ostrzeżenie: (0%)
-----


Zrobione i przepraszam - już będę pamiętał o takich szczegółach :-)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 3.05.2025 - 05:56