Thread overview
Öğrenmelik: opIndex() içermeyen yapı!
May 24, 2022
Salih Dincer
May 24, 2022
Salih Dincer
May 24, 2022
Ali Çehreli
May 24, 2022
Ali Çehreli
May 24, 2022
Ali Çehreli
May 25, 2022
Salih Dincer
May 25, 2022
Ali Çehreli
May 26, 2022
Salih Dincer
May 24, 2022

Yapı bir dizi değil ki! Yasal mı, bu nasıl olur? Şöyle bir kod parçası var; deneysel bir programdan alınma:

import std.stdio;
struct BirYapı { int[] i; }
void main()
{
    auto b = new BirYapı(new int[2]);
    b[0].writeln(": @", &b[0]);
} /* ÇIKTISI:
BirYapı([0, 0]): @7FDDB2F83000
*/

İçeriğinde opIndex() tanımlanmadığı için merak ettim. Sanırım ilk elemanın adresi aslında yapının, yoksa içindeki diziye eriştiğimiz söylenemez, değil mi?

Teşekkürler...

May 24, 2022

On Tuesday, 24 May 2022 at 05:26:34 UTC, Salih Dincer wrote:

>

Yapı bir dizi değil ki! Yasal mı, bu nasıl olur?

Ben böyle bir şey bilmiyordum! Anladığım kadarıyla yasal! İşin ilginci kodu geliştirdiğimde ikinci bir null üye gördüm. Çünkü int[] i yanına, yeni bir üye işlev olan int opIndex() eklendiğinde ortaya çıktı:

void main()
{
  struct BirYapı
  {
    int[] i;
    int opIndex(size_t index) { return i[index]; }
  }
  auto b = new BirYapı(new int[2]);
  b.i[1] = 1;

  import std.stdio;
  b[0].writeln(": @", &b[0]);
  foreach(n, ref a; b.i)
  {
    n.writeln(": @", &a);
  }

  auto i = BirYapı([1, 2, 3]);
  assert(i[0] == 1);
  assert(i[1] == 2);
  assert(i[2] == 3);
} /* ÇIKTISI:
BirYapı([0, 1], null): @7F4274288000
0: @7F4274289000
1: @7F4274289004
*/

Bir şey daha, sanırım (yok eminim! 😀) yapıyı new operator ile kurmadığınızda bu köşeli parantez olayı olmuyor. Çünkü şu hatayı alıyorum:

>

globalVar.d(50): Error: no [] operator overload for type BirYapı

Anladığım kadarıyla new ile kurunca yapının her üyesine bu şekilde erişmek mümkün!?

Allah Allah!!!

May 24, 2022
On 5/23/22 22:26, Salih Dincer wrote:

>      auto b = new BirYapı(new int[2]);
>      b[0].writeln(": @", &b[0]);

Daha sonradan farkettiğin gibi, her gösterge bir dizi gibi kullanılabilir. (D'nin C kodlarını olduğu gibi kullanabilme isteklerinden birisinin etkisi.) Burada şanssız biçimde üye de dizi olunca kafamız karışıyor. Halbuki dizi gibi kullanılan, b'nin kendisidir. Şu program açıklayıcı olabilir:

import std.stdio;
import core.stdc.stdlib;

struct S {
  int i;
}

void main() {
  enum n = 10;

  // Birden fazla S için yer ayırıyoruz.
  // Bunun yerine calloc() vs. de kullanabilirdik.
  // (Not malloc belleği sıfırlamaz. İçinde çök değerler
  // görebiliriz.)
  auto v = malloc(n * S.sizeof);

  // malloc void* döndürür:
  static assert (is (typeof(v) == void*));

  // O bellek alanını S'ler için kullanmak için cast:
  auto ptr = cast(S*)v;

  // Şimdi bizim tür:
  static assert (is (typeof(ptr) == S*));

  // Ve bir C dizisi gibi kullanılabilir:
  // Dikkat: Buradaki örnekte çöp değerlerin
  // üzerine S atamakta bir tehlike yok ama
  // daha karmaşık türlerde program göçecektir
  // çünkü atama işlemi iki adımdan oluşur:
  // eski üyeleri sonlandır ve yeni üyelere
  // yeni değerler ver. (Eski nesneler çöp
  // değerlerle sonlandırılırken göçecektir.
  // (Burada değil, başka programlarda.))
  ptr[n / 2] = S(1_111_111_111);

  // Ve bir D dizisine dönüştürülebilir. (Çok
  // kullanışlı bir söz dizimi.)
  auto dizi = ptr[0..n];

  static assert (is (typeof(dizi) == S[]));

  writeln(dizi);
}

Ali

May 24, 2022
On 5/24/22 06:42, Ali Çehreli wrote:

>    // Şimdi bizim tür:
>    static assert (is (typeof(ptr) == S*));
>
>    // Ve bir C dizisi gibi kullanılabilir:

Şurada geçiyor:

  http://ddili.org/ders/d/gostergeler.html#ix_gostergeler.[]

>    // [...] (Eski nesneler çöp
>    // değerlerle sonlandırılırken göçecektir.

Öyle olmaması için emplace kullanabilirdim:

  http://ddili.org/ders/d/bellek_yonetimi.html#ix_bellek_yonetimi.emplace

Ali

May 24, 2022
On 5/24/22 06:52, Ali Çehreli wrote:

>    http://ddili.org/ders/d/gostergeler.html#ix_gostergeler.[]

Düzeltmeye çalışıyorum:

  <http://ddili.org/ders/d/gostergeler.html#ix_gostergeler.[]>

Eğer o da olmazsa o sayfada "Dizi erişim işleci [] ile kullanımı" başlığını arayabilirsiniz. :)

Ali

May 25, 2022
On Tuesday, 24 May 2022 at 13:42:44 UTC, Ali Çehreli wrote:
> Daha sonradan farkettiğin gibi, her gösterge bir dizi gibi kullanılabilir. (D'nin C kodlarını olduğu gibi kullanabilme isteklerinden birisinin etkisi.) [...]

Yani C'de de böyle, diziden farklı olarak göstergelerde köşeli parantez kullanımı var mı?

Teşekkürler...
May 24, 2022
On 5/24/22 21:50, Salih Dincer wrote:
> On Tuesday, 24 May 2022 at 13:42:44 UTC, Ali Çehreli wrote:
>> Daha sonradan farkettiğin gibi, her gösterge bir dizi gibi
>> kullanılabilir. (D'nin C kodlarını olduğu gibi kullanabilme
>> isteklerinden birisinin etkisi.) [...]
>
> Yani C'de de böyle, diziden farklı olarak göstergelerde köşeli parantez
> kullanımı var mı?

Evet ve aslında dizi[i] kullanımı, C'den beri perde arkasında aşağıdaki kullanımın aynısıdır:

  *(dizi + i)

Burada hatırlatmak gerek: Gösterge aritmetiğine göre, i eklemek, "i adet eleman öteyi göstermek" anlamına gelir, "i bayt öteyi" değil.

Ali

May 26, 2022

On Tuesday, 24 May 2022 at 13:42:44 UTC, Ali Çehreli wrote:

>

On 5/23/22 22:26, Salih Dincer wrote:
[...] Şu program açıklayıcı olabilir:

import std.stdio;
import core.stdc.stdlib;

struct S {
int i;
}
[...]

Hocam D'nin gözünü seveyim bea! Kodu C'de yazayım dedim o tutorial senin burdaki benim uğraştım durdum 😀

Neyse, bu örnek çok iyi oldu. Neticede bilgilerimizi tazeledik. Hele ki bunca seneden sonra, devamının olduğunu bildiğimiz bir işaretçi üzerinde, sanki bir diziymiş gibi kullanılabildiğini öğrenmek güzeldi.

Ben de D özelliği zannediyordum, teşekkürler...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct S {
  int8_t id;
  char name[6]; // 5 + 1(\0)
};

const int CITY = 35;

int main()
{
  int n = 0;
  struct S s, *ptr;
  ptr = (struct S*) malloc(CITY * sizeof(struct S));

  printf("ilk adresi: %p\n", ptr); // 0x55aca99ec260
  for(int i = 0; i < CITY; ++i)
  {
    ptr[i].id = i + 1;
  }
  printf("plaka kodu: %d\n", ptr[n].id);
  strcpy(ptr[n].name, "adana");
  printf("ilin ismi : %s\n", ptr[n].name);

  n = CITY - 1;

  printf("plaka kodu: %d\n", ptr[n].id);
  strcpy(ptr[n].name, "izmir");
  printf("ilin ismi : %s\n", ptr[n].name);

  for(int i = 0; i < CITY; ++i)
  {
    printf("%d: %s\n", ptr[i].id, ptr[i].name);
  }
  printf("son adresi: %p\n", &ptr[n]); // 0x55aca99ec34e
/* Son adresinden (...34e) ilk adresi (...260)'ı çıkarınca
 * 0xEE kalıyor ki bu onluk 238 demek ve bunu 34'e bölünce 7
 * değeri bulunuyor. Yani S yapısı 1 + 6 baytdan oluşuyor.
 */

  s = ptr[0];
  ptr[0].id = 0;
  printf("%s'nın plaka kodu: %d\n", s.name, s.id);

  return 0;
} /* ÇIKTISI:
ilk adresi: 0x55aca99ec260
plaka kodu: 1
ilin ismi : adana
plaka kodu: 35
ilin ismi : izmir
1: adana
2:
3:
...
35: izmir
son adresi: 0x55aca99ec34e
adana'nın plaka kodu: 1
*/