Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]inkrementacja i dekrementacja zmiennej typu string
Forum PHP.pl > Forum > Przedszkole
qpanas
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!
netmare
a jaki wynik wg. Ciebie powinna mieć inkrementacja ciągu abc?
qpanas
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ę.
netmare
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
qpanas
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.
netmare
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
Kicok
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
qpanas
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
netmare
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
qpanas
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 ;-)
dr_bonzo
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].
Pilsener
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
qpanas
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 ;-)
Piniek
Przenoszę na przedszkole, proszę o dodanie tagu do tematu i poprawienie bbcode.
qpanas
Zrobione i przepraszam - już będę pamiętał o takich szczegółach :-)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.