Thread overview
Enum'u Anlamak!
May 19, 2012
Salih Dinçer
May 19, 2012
Salih Dinçer
May 19, 2012
Salih Dinçer
May 28, 2012
Salih Dinçer
Mar 10, 2013
Salih Dinçer
May 20, 2012

Merhaba,

Az önce yanlış anlamları engellemek ve doğruyu kavramak için küçük bir deneme kodu yazdım. Meğer enum, bilgisayarın kapasitesine (32 bit/64 bit) göre adreslenebilen sanal bir SINIR'a yerleştirilen sabit değişmezlerden (immutable) ibaretmiş.

Yani bunu bir cetvel veya sayı ekseni gibi düşünebilirsiniz. Her sayı çizgisine yerleştirilen (işaretlen) bir isimler topluluğumuz var. Ancak kural gereği bunlar arasında sayıları yok farzedemiyoruz. Onlar hala orada; sadece isimsizler. Bakınız şu kod bunu kanıtlıyor:

Alıntı:

>
> import std.stdio;
>
> immutable SINIR = size_t.max;
>
> enum Say {
>     Bir = 1, Son = SINIR
> }
>
> void main() {
>     Say deneme = Say.Bir;
>
>     writeln ("SINIR = ", SINIR);
>     writeln(" - ", deneme);
>
>     for ( ; deneme != SINIR; deneme++)
>         if (deneme % (SINIR / 8) == 0) writefln("\t%d", deneme);
>
>     writeln(" - ", deneme);
> }
> ```

>
**ÇIKTISI:**
'SINIR = 4294967295
- Bir
       536870911
       1073741822
       1610612733
       2147483644
       -1610612741
       -1073741830
       -536870919
       -8
- Son'

**Dip Not:** Bu kod 32 bit sistemde denenmiştir. Muhtemelen 64 bit sistemde bu sayılar daha büyük olacak ve işlem daha uzun sürecek.

Sevgiler, saygılar...

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
May 20, 2012

Aynı kodu C#'da denedim de belki eksi (-) int.MaxValue'den başlatsaydım 2³²-1 kadar bir kapasite olacaktı. Bunda ise 2³¹-1 kadar bir alana değer yerleştiriyor:

using System;

namespace applications {
   class test {
       const int SINIR = int.MaxValue;

       enum Say {
           Bir = 1, Son = SINIR
       }

       static void Main(string[] args){
           Say deneme = Say.Bir;

           Console.WriteLine ("SINIR = {0}", SINIR);
           Console.WriteLine (" - {0}", deneme);

           for ( ; (int)deneme != SINIR; deneme++)
               if ((int)deneme % (SINIR / 8) == 0) Console.WriteLine("\t{0}", deneme);

           Console.WriteLine (" - {0}", deneme);
       }
   }
}

Diğer dillerde nasıl bilmiyorum, denemedim ama D'de SINIR'a ulaşıldığı zaman bir anda size_t'nin eksisine ışınlanıp 0'a yaklaşıyor. Bir nevi sayı ekseninin her iki ucunun bir çember çevresinde birleşmesi gibi.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 20, 2012

Çıktısını unutmuşum!

Ayrıca eklemeliyim; VS uint'e izin vermiyor. Overloading falan fıstık diyor. D'de ise sanki taşmaya izin verdiği gibi tür dönüşümüne gerek bırakmıyor. D çok güzel ve esnek bir dil...:)

Alıntı ("C# ÇIKTISI"):

>

SINIR = 2147483647

  • Bir
    268435455
    536870910
    805306365
    1073741820
    1342177275
    1610612730
    1879048185
    2147483640
  • Son

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 20, 2012

Güzel deneyler... :)

Ek olarak, kaç bitlik mimaride olursa olsun D'de enum'un asıl türü açıkça seçilebiliyor. Şu enum'un değerleri 8 bitten oluşurlar:

enum Renk : ubyte { mavi, yeşil }

Veya S isminde bir yapı ile:

enum BirŞey : S { bir = S(0, 1), iki = S(2, 3) }

Ancak, S'nin enum olarak kullanılabilmesi için öncelikle opCmp() şarttır. ++ işlecinin uygulanabilmesi için de opUnary!"++" şarttır:

struct S
{
   int i;
   int j;

   int opCmp(S sağdaki) const
   {
       return (i == sağdaki.i
               ? j - sağdaki.j
               : i - sağdaki.i);
   }

   // Garip bir ++ davranışı
   auto ref opUnary(string op)() if( op == "++" ) {
     ++i;
     ++j;
     return this;
  }
}

void main()
{
   auto b = BirŞey.bir;
   ++b;
}

Burada da görüldüğü gibi, opUnary!"++" içinde oluşan değer enum'un tanımında bulunmak zorunda değil. Esneklik güzel ama senin de söylediğin gibi ara değerler yine de oradalar.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

May 28, 2012

Ali hocamın değindiği son örnek bana çok şaşırtıcı geliyor. Bunu şimdilik bir kenara bırakırsak şurada (http://ddili.org/forum/post/6014) bahsettiğim yapı içindeki elemanlarla gezmek olayı için anahtar teşkil edebilir mi?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 10, 2013

Enum'ları biraz daha anlamak için şu başlığı da takip etmelisiniz...:)

http://ddili.org/forum/thread/998

Ama her şeye rağmen anlayamadığımız veya dilin bize olanak olarak vermesini gerektiğini düşündüğümüz davranışları var. Belki de bir olanak vardır ve ben, onu henüz bilmiyorumdur?

Örneğin şu örnek derlenmez:

import std.stdio;

enum Günler: int {
   Pazartesi = 2,
   Salı      = 3,
   Çarşamba  = 5,
   Perşembe  = 7,
   Cuma      = 11,
   Cumartesi = 13,
   Pazar     = 17
}

void main() {
 Günler gün = Günler.Cuma;
 byte test = gün;/* Derlenmesi için bu satırı gizlemelisiniz...
 int test = gün;//*/

 typeid(gün).writeln();
}/*
Derleme Hatası:  cannot implicitly convert expression (gün) of type Günler to byte
*/

Çübkü int türündeki bir sabiti byte türündeki test değişkenine eşitlemeye çalışıyoruz. Eşitliğin sol tarafındaki tür eşitlenene göre küçüktür. Ancak burada anlamaya çalıştığım, derleyici enum'un bir int türü olduğunu biliyorsa ve/veya bize haber verebiliyorsa tür şablonu kullanarak ve is işleçi ile biz bunu sorgulayabilmeliyiz, değil mi?

bool testType(T)() if(is(T == int)) {
 return true;
}

Tamam, testType!int ile bunu yapabiliyoruz. Ama işin içine enum girince bize bildirlen sadece adı ya peki kurulurken ki türü?

Sevgiler, saygılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 10, 2013

Alıntı (Salih Dinçer):

>

tür şablonu kullanarak ve is işleçi ile biz bunu sorgulayabilmeliyiz, değil mi?

Evet: std.traits.OriginalType;

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]