Bu kod neden A'dan Z'ye kadar harf yazdırmıyor?


435
<?php
for ($i = 'a'; $i <= 'z'; $i++)
    echo "$i\n";

Bu snippet aşağıdaki çıktıyı verir (yeni satırlar boşluklarla değiştirilir):

abcdefghijklmnopqrstu vwxyz aa ab ac ad ae af ag ah ai aj ak al am a ao ap aq ar as at au av aw ax ay az ba bb bc bd olmak bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cv cw cx cy cz da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et ab ev ew ex ... on to yz


31
Sözdizimi sizi tersine ikna etmeye çalışsa bile PHP C değildir.
joni

3
Bu benim için çok küçük bir değişiklikle çalışıyor: for ($ i = 'a'; $ i! = 'Aa'; $ i ++) {echo "$ i \ n"; }
Gerçeküstü Düşler

2
Bu PHP ile ilgili yorum C değildir - en keskin olanıydı, örneğin: c: char c = 'a'; php: ile aynı değildir, $c = 'a';nokta C karakter char (karakter 1 sembolü) vardır, ancak U değil PHP söylemek - PHP değil, $c = 'a';bu sadece 1 karakterli bir dize anlamına gelir. Bu yüzden U, PHP'de 28 karakter arasında yeterince döngü yapamaz. Umarım her programcı, daha güçlü olmalarına yardımcı olacak Matematik uygulamalarını unutmadan, düşük seviyeli dilleri ve güçlü yazmayı öğrenir.
Arthur Kushman

Vay bu gerçekten harika, ama neden "z" durmadı
Prasanth Bendra

Eşitlik ( ==veya !=) kullanarak beklenen son noktayı elde etmenin bir yolu için ilgili soruya bu cevabı inceleyin .
IMSoP

Yanıtlar:


342

Gönderen docs :

PHP, Perl'in C değil karakter değişkenleri üzerindeki aritmetik işlemlerle ilgili kuralını izler.

Örneğin, Perl 'Z'+1dönüşür 'AA'C ise, 'Z'+1dönüşür '['( ord('Z') == 90, ord('[') == 91).

Karakter değişkenlerinin artırılabileceğini ancak azaltılamayacağını ve buna rağmen yalnızca düz ASCII karakterlerinin (az ve AZ) desteklendiğini unutmayın.

Yorumlar: - Bir sözlükbilimsel karşılaştırma olduğu
da belirtilmelidir. (Çünkü. Amakarşılaştırma ilk kez yanlıştır.)Meselanezaman işe yarayacaktı.<='z'+1 ≤ 'z''z'+1 = 'aa' ≤ 'z''za' ≤ 'z'$i == 'z'

Burada örnek .


Hah .. bu delilik! Hep kullandım ord()bu yüzden bunu hiç fark etmedim.
mpen

68
Tamlık için, "<=" ifadesinin sözlükbilimsel karşılaştırma olduğunu da eklemelisiniz, yani 'z' + 1 ≤ 'z'. ('Z' + 1 = 'aa'≤'z' olduğu için, ancak 'zz'≤'z' karşılaştırma ilk kez yanlıştır.) Örneğin, $ i == 'z' 'nin çalışacağı zaman kırılır.
ShreevatsaR

6
ShreevatsaR'ın dediği gibi, karşılaştırıcıdır, sorun olan aritmetik değil, ++ operatörüne odaklanmayın
slf

10
@ShreevatsaR: aslında, 'yz' + 1 = 'za'. Başarısız olan ilk karşılaştırma 'za' <= 'z'
Milan Babuškov

2
Yorumlar için teşekkürler beyler! Evet, kilit nokta olduğunu 'aa'olduğunu sözlük sırasında daha küçük 'z'döngü devam yüzden o. Ve durur 'yz'çünkü 'za'daha büyüktür z. Bu örneği kontrol edin .
CMS

123

'Z' değerine ulaşıldığında (ve bu, aralığınız dahilinde geçerli bir sonuç olduğundan, $ i ++ bunu sırayla bir sonraki değere yükseltir), sonraki değer 'aa' olur; ve alfabetik olarak, 'aa' <'z' dir, bu nedenle karşılaştırma asla karşılanmaz

for ($i = 'a'; $i != 'aa'; $i++) 
    echo "$i\n"; 

55
'Z' ++ = 'aa' ama 'aa' <'z' tuhaf. Bu mantık çok iyi akmıyor.
Matthew Vines

19
@ Mathew: Alfabetikleştir. Önce "aa" gelirdi, bu yüzden "z" dizesinden "küçük" olur. Döngü 'zz' ile biter çünkü alfabetik olarak "büyüktür" (sonra gelir) 'z'. Bir şeyi "artırabileceğiniz" ve daha düşük bir değer elde edebileceğiniz anlamıyla mantıksızdır, ancak alfabetik anlamda mantıklıdır.
eldarerathis

2
Karakter artırıcı Perl mantığıdır (CMS'nin dokümanlardaki alıntısına bakın). 'Aa' <'z' karşılaştırması standart dize karşılaştırma mantığıdır. Garip değil, nasıl kullanılacağını anladıktan sonra ... buradaki cevaplardan, birçok insan kullanmıyor.
Mark Baker

5
@eldarerathis Oh Nasıl çalıştığını kesinlikle anlıyorum. Aynı zamanda tuhaf buluyorum.
Matthew Vines

2
Aynı mantıksal diziyi takip eden Excel sütunlarıyla oynamak benim için son derece yararlı
Mark Baker

97

Diğer cevaplar yayınlanan kodun gözlemlenen davranışını açıklar. İstediğinizi yapmanın bir yolu (ve daha temiz kod, IMO):

foreach (range('a', 'z') as $i)
    echo "$i\n";

ShreevatsaR'ın aralık işlevi hakkındaki yorumuna / sorusuna yanıt olarak : Evet, "sağ uç noktası" üretir, yani işleve iletilen değerler aralıktadır. Örneklemek gerekirse, yukarıdaki koddan çıktı:

a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z

2
Range () doğru bitiş noktasını içeriyor mu? Diğer dillerdeki deneyimlerden bu beklenmedik bir durum!
ShreevatsaR

1
@ShreevatsaR: Evet, range () "sağ" bitiş noktasını verir, daha fazla bilgi için düzenlenmiş cevabıma bakın (ve fonksiyonun bağlantısını takip edin).
GreenMatt

1
Ne diyebilirim… daha fazla PHP deliliği. :-) Hangi range () yönteminin bu şekilde çalıştığını bildiğim başka bir dil yok. (Kesinlikle, Haskell veya Python deyin.) Dijkstra bunun hakkında bir şey yazmadı mı?
ShreevatsaR

10
Delilik PHP'nin tutarsızlığı içindedir. aralık ('A', 'CZ') ++ artırıcıdan tamamen farklı çalışır ve elde edilen dizi sadece üç değer içerir: A, B ve C
Mark Baker

35

Diğerleri, PHP'nin neden beklediğinizi göstermediğini zaten söyledi. İstediğiniz sonucu nasıl elde edeceğiniz aşağıda açıklanmıştır:

<?php
for ($i = ord('a'); $i <= ord('z'); $i++)
    echo chr($i);
?>

2
Gereksiz. ord () yapmanıza gerek yok, sadece döngüyü sonlandırmak için doğru karşılaştırma
Mark Baker

2
+1 PHP'nin daha eksantrik özelliklerinden birine aşina olmadığında çok daha anlaşılır.
lonesomeday

1
Bu, kendi kendini belgeleyen kodun mükemmel bir örneğidir. Kolayca anlaşılabilir, b / c sıralı değerleri kullanır ve sonra değişkeni karakter olarak görüntüler. Maksimum değer için test aşağıdaki gibi yalnızca bir kez belirlenirse for-loop daha verimli olurdu: "for ($ i = ord ('a'), $ max = ord ('z'); $ i <= $ maks; $ i ++) {"
slevy1


4

Bu kodu deneyin. Bu kodun size yardımcı olacağını düşünüyorum.

$alphas = range('A', 'Z');
foreach($alphas as $value){
    echo $value."<br>";
}

26 harfi sırayla görüntüler.


2
<?php

$i = 'a';
do {
echo ($j=$i++),"\r\n";
} while (ord($j) < ord($i));

?>

2

Ayrıca bu kullanılabilir:

for ($i = 'a'; $i <= 'z'; $i=chr(ord($i)+1))
    echo "$i\n";

2

PHP harflerin döngü fonksiyonuna sahiptir ve tek karakterlerin ötesine geçebilir; geri kalanı şu şekilde yapılacaktır: aa ab ac ... zz, vb.

Bunu dene:

<?php
for ($i = 'a'; $i !== 'aa'; $i++)
    echo "$i\n";
?>

0

Yukarıdaki cevaplar neler olup bittiğine dair anlayışlı olsa da ve oldukça ilginç olsa da (bunun böyle davranacağını bilmiyordum ve nedenini görmek güzel.

En kolay düzeltme (belki de en anlamlı olmasa da) sadece koşulu $ i olarak değiştirmek olacaktır! = 'Z'

<?php
for ($i = 'a'; $i != 'z'; $i++)  
    echo "$i\n";
?>

4
Unutmayın ki bu size z ye değil, sadece y 'ye verecek
Mark Baker

doh! evet, iyi bir nokta. Hem artışın hem de karşılaştırmanın arkasındaki mantığı görebiliyorum, ancak bazen $ a ++ <$ a
jon_darkstar

0

PHP 'AA'yı' Z'den daha az dikkate almaz. Bunu yapmanın en iyi yolu:

for($i = 'a'; $i != 'aa'; $i++) {
  echo $i;
}

abcdefghijklmnopqrstuvwxyz


0

Belki de bu kod işe yarayacaktır. Kolay ve anlaşılabilir:

<?php
$ascii_val = ord("a");
for($i=$ascii_val;$i<$ascii_val+26;$i++){
echo chr($i)."\n";
}
?>

burada 26, alfabedeki toplam harf sayısıdır.


-3

Vay be gerçekten bu konuda bilmiyordum ama onun büyük bir kod değil döngü sonra yankı "z" deneyebilirsiniz Mark Kesinlikle Doğru Metodunu kullanın ama alternatif istiyorsanız o zaman bu da deneyebilirsiniz

<?php
for ($i = "a"; $i = "y"; $i++) {
    echo "$i\n";
    if ($i == "z") {}
}
echo "z";
?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.