Go Programlama Dili
  • KİTAP HAKKINDA
    • GİRİŞ
    • Katkıda Bulunanlar
  • BÖLÜM 1 (Ön Eğitim)
    • Golang Hakkında
    • Sıkça Sorulan Sorular
    • Go Derleyicisi Kurulumu
    • VSCode Go Eklentisi Yükleme
    • Go Projesi Oluşturma
    • Merhaba Dünya
    • VSCode Varsayılan Hata Ayıklayıcıyı Seçme
    • Farklı Platformlara Build (İnşa) Etme
    • Klasör Build Etme
    • Paketler
    • Yorum Satırı
    • Veri Tipleri
    • Aritmetik Operatörler
    • İlişkisel Operatörler
    • Mantıksal Operatörler
    • Atama Operatörleri
    • Değişkenler ve Atanması
    • Sabitler
    • Kod Gruplama İşlemi
    • Tür Dönüşümü
    • Bölüm 1 Sınav
  • BÖLÜM 2 (İşlem Yapma)
    • Fonksiyonlar
    • Fonksiyon Çeşitleri
    • Anonim Fonksiyonlar
    • Boş Tanımlayıcılar
    • Döngüler
    • If-Else
    • Switch
    • Defer
    • Pointers (İşaretçiler)
    • Bölüm 2 Sınav
  • BÖLÜM 3 (Gruplama)
    • Struct
    • Anonim Struct'lar
    • Struct Fonksiyonlar (Methodlar)
    • Diziler (Arrays)
    • Dilimler (Slices)
    • Range
    • Map
    • Interface
    • Dinamik Değişkenler
    • Generics
  • BÖLÜM 4 (Eş zamanlılık)
    • Goroutine
    • Kanallar (Channels)
    • Anonim Goroutine Fonksiyonlar
    • WaitGroup ile Asenkron İşlemleri Beklemek
    • Mutex ile Asenkron İşlem Sırası
    • Zamanlayıcılar (Tickers)
    • Select
  • BÖLÜM 5
    • init() Fonksiyonu (Ön Yükleme)
    • Import (Kütüphane Ekleme) Yöntemleri
    • Dışa Aktarma (Exporting)
    • Print Fonksiyonu Birkaç İnceleme
    • Format ve Kaçış Karakterleri
    • Çok Satırlı String Oluşturma
    • Sprintf
    • Golang'te Kullanıcıdan Giriş Alma
    • Testing (Test Etme)
    • Panic & Recover
  • BÖLÜM 6 (Paketler)
    • Strings
    • os/exec (Komut Satırına Erişim)
    • Komut Satırı Argümanları (Args)
    • Komut Satırı Bayrakları (Flags)
    • os/signal
    • Sort (Sıralama)
    • Strconv (String Çeviri)
    • Log (Kayıt)
    • Paket (Kütüphane) Yazmak
    • Regexp (Kurallı İfadeler)
  • BÖLÜM 7 (Dosya İşlemleri)
    • Çapraz Platform Dosya Yolları
    • İşletim Sistemini Görme
    • Dosya Varlığı Kontrolü
    • ioutil ile Dosya Okuma ve Yazma
    • Bir Dizindeki Dosya ve Klasörleri Sıralama
    • XML Parsing (Ayrıştırma)
    • JSON Parsing (Ayrıştırma)
      • Dinamik JSON Parsing Yöntemleri
    • ini Dosyası Okuma ve Düzenleme
    • Web Scrapper (goquery)
    • chromedp (Web Driver)
  • VERİTABANI
    • sqlite3
    • MySQL
    • MongoDB
    • GORM
  • Web Sunucu (Server), Ağ İşlemleri
    • net/http ile Web Server Oluşturma
    • HTML Şablonlar (Templates)
    • Statik Kütüphanesi ile Dosyaları Uygulamaya Gömme
    • Gin Web Kütüphanesi
      • Gin Dosya Yükleme
    • gRPC
    • Heroku'da Go Uygulaması Yayınlama
    • HTTP İstekleri (Requests)
    • RabbitMQ
      • RabbitMQ Kurulumu
      • Basitçe RabbitMQ Kullanımı
  • GUI (Grafiksel Kullanıcı Arayüzü)
    • WebView
    • notify (Bildirim)
  • Mikro-denetleyiciler
    • Gobot ile Arduino Yanıp-Sönen LED Yapımı
    • Tinygo ile Küçük Yerler için Golang
  • CLI
    • 🐍Cobra CLI
  • ⚙️Yapılandırma
    • 🐍Viper
  • Pratik Bilgiler
    • Go Geliştiricileri için Makefile
    • Derleme (Build) Detayını Görme
    • Visual Studio Code için Golang Özelleştirmeleri
  • 👾PLUS
    • Uber Go Stil Kılavuzu
Powered by GitBook
On this page

Was this helpful?

  1. BÖLÜM 2 (İşlem Yapma)

Pointers (İşaretçiler)

PreviousDeferNextStruct

Last updated 4 years ago

Was this helpful?

İşaretçiler ile nesnenin bellekteki adresi üzerinden işlemler yapabilir. Daha önceden işaretçileri içeren bir dil kullanmamış veya herhangi bir programlama dili de kullanmamış olabilirsiniz. Bu yüzden daha iyi anlamanız için işaretçilerin çalışma mantığını bilmemiz gerekir.

Örnek olarak a isminde bir değişkenimiz olsun. Bu değişkenimiz tam sayı (int) tipinde 8 değerini saklıyor olsun. Bu da Go dilinde aşağıdaki gibi oluyor.

var a int = 8

Bu değişkenimizi oluşturduktan sonra programımız çalışmaya başlayınca işletim sistemimiz bu değişkene özel, bellek (RAM) üzerinde bir alan ayıracaktır. Programın geri kalanında değişkenimizin değerine bu alan üzerinden ulaşılacaktır. Yani bir değişken oluşturduğumuzda bellek üzerinde aşağıdaki resimdeki gibi bir alan oluştuğunu hayal edebilirsiniz.

Yukarıdaki resimde mor renkli olarak gördüğümüz ifade ise değişkenimizin bellekteki adresidir. (Bu adres temsilidir. Zaten sürekli olarak değişen birşeydir.)

Peki Go'da işaretçileri nasıl kullanırız?

Bir program senaryosu belirleyelim. Bu programımızda yukarıdaki gibi a isminde int tipinde 8 değerini tutan bir değişkenimiz olsun. Ve a değişkenimize 5 ekleyen bir fonksiyonumuz olsun. Son olarak a'yı ekrana bastıralım.

package main

import "fmt"

func main() {
	a := 8
	ekle(a)
	fmt.Println(a)
	//sonucumuz yine 8 olacak
}
func ekle(v int) {
	v += 5
}

Yukarıdaki örnekte a değişkenini ekrana bastırdığımızda sonucun hala 8 olduğunu görüyoruz. Halbuki ekle fonksiyonunun içerisinde gördüğümün gibi 5 ekliyoruz.

a değişkeninin değişmeme sebebi şudur: ekle fonksiyonunun parametresi olarak int tipinde v değişkenini oluşturduk. v değişkenimiz aslında a'dan gelen değeri kullanmamızı sağlıyor. Yani bize a'nın kendisini vermiyor. O yüzden v üzerinde değişiklik yaptığımızda a'ya yansımayacaktır.

a değişkenini değiştirebilmemiz için bize a'nın bellekteki adresi gerekiyor. Bunun için de & (ampersand) işaretini kullanabiliriz.

Örnek vermek gerekirse:

func main() {
	a := 8
	fmt.Println(&a) //Çıktımız: 0xc0000b8010
}

Artık a'nın bellekteki adresini öğrenebiliyoruz. Sıra geldi bu adres üzerinden a'nın değerine ulaşabilmeye.

Bunun için de * (yıldız) işaretini kullanabiliriz.

func main() {
	a := 8
	fmt.Println(&a) //Çıktımız: 0xc0000b8010
	b := &a
	fmt.Println(b) //Çıktımız: 0xc0000b8010
	fmt.Println(*b) //Çıktımız: 8
}

Yukarıdaki örneği incelediğimizde b değişkenine a'nın adresini atadık. b'yi bastırdığımızda a'nın bellekteki adresini görebiliriz. Aynı zamanda *b şeklinde kullanarak a'nın içindeki değere de ulaşabiliriz. Bu durumda a ve bdeğişkenleri aynı bellek alanını temsil ediyorlar.

a değişkenine b üzerinden değişiklik yapmak için aşağıdaki yöntemi uygulayabilirsiniz.

package main

import "fmt"

func main() {
	a := 8
	b := &a
	*b = 10
	fmt.Println(a) //10
}

En başta kurguladığımız senaryoyu işaretçiler ile kolayca yapabiliriz.

package main

import "fmt"

func main() {
	a := 8
	ekle(&a)
	fmt.Println(a) //Çıktımız: 13
}
func ekle(v *int) {
	*v += 5
}

Yukarıdaki örneği incelediğimizde, ekle fonksiyonumuzu oluştururken parametre olarak verdiğimiz v değişkeninin tipinde önce * işareti koyduk. Bunun sebebi v değişkeni ile fonksiyonumuza gelecek olan adresin içindeki değere ulaşabilmektir.

ekle fonksiyonunun içerisindeki v'yi kullanırken de başına * koyarak kullandık.

main fonksiyonumuzda ekle fonksiyonunu çağırırken de a değişkenini & işareti kullanarak bellekteki adresi ile verdik.

Bu sayede a değişkenine bellekteki adresi ile müdahale etmiş olduk.

Değişkenin RAM üzerindeki Alanı (Temsili)
Ampersand kullanımı