Matris İşlemleri [ C Programlama ]

Başlarken

Adam Asmaca ve Mayin Tarlasi sonra pişti oyununu C ile yazmaya başlayacaktım. Kurallarını falan da araştırıp öğrendim biraz. Ancak kağıtları konsolda sembolik olarak göstermenin tatmin edici bir yöntemini bulamadım henüz. O yüzden bir süreleğine oyunlara ara veriyorum :) Matrisler üzerinde yapılabilecek işlemler de ilginç olabilir düşüncesiyle onunla ilgili bir program yazmaya karar verdim.

Programlama

// Matris üzerinde yapılabilecek işlemleri şöyle bir düşünürsek; iki matrisi toplamak/çıkarmak/çarpmak, bir matrisi bir sabit ile çarpmak/bölmek, bir matrisin transpozesini almak, bir matrisin determinantını almak ilk aşamada yapılabilecek işlemler. Bunları bir menü şeklinde kullanıcıya sunabiliriz.

matris-islemleri-menu

// İşlemlerin nasıl yapıldığına geçmeden önce matrislerin saklanma ve işlenme durumundan bahsedecek olursak: Farklı bir yöntem oldu uyguladığım şekilde. Kullanılabilirlik açısından ne kadar iyi olduğunu bilemiyorum :). Şöyleki, bazı durumlarda bir matris bazı durumlarda iki matris üzerinde işlem yapacağız. Bir de girilen matrisin boyutlarına göre sonuç matrisimiz var tabi. O yüzden bunlar değişiklik göstereceğinden dolayı dinamik olarak matrislerin saklanacağı alanları ayırdım. Bu matrisleri gösteren pointerlari tutabilmek için ise o türü saklayabilecek bir dizi tanımladım. Genel olarak dizinin gösterdiği ilk matris 1.matrisimiz, gösterdiği ikinci matris 2.matrisimiz ve gösterdiği üçüncü matris ise sonuç matrisimiz olacak. (determinant işlemi hariç)

// Matrislerin artık nerede ne şekilde olacağına karar verdiğimize göre diğer duruma geçelim. Fonksiyonlara matrislerin boyutlarını -ordan oraya- göndermek istemedim. Matrisin gittiği her yere satır ve sütun sayısını da götürsün istedim. Bu durumda matris için yer ayırırken 1 satır ve 1 sütun fazla yer ayırdım. Matrisin 0.satırdaki 1.sütunda satır sayısı, 2.sütununda ise sütun sayısı saklanacak.

// Bu ilginç durumları açıkladıktan sonra. Matrisleri gösteren pointerlari tutan dizinin global olma sebebine gelelim. Bir çok fonksiyon arasında matrisleri ordan oraya göndermektense global olarak tanımlayıp tüm fonksiyonlardan onlara ulaşmayı tercih ettim. Sonuçta hangi matrisin hangisi olduğunu biliyorum.

// İki matrisi çarpma kodunu zaten bir çok kaynaktan bulabilirsiniz. Onun hakkında bir şey yazmayacağım.

// Ama determinant hesaplamasını ilk defa yaptım. Recursive bir yapı kullandım. 4x4 luk bir matriste 3x3 luk matrislerinde determinantının bulunması gerekir. Bu 3x3 luk matrisler içinde 2x2 lik matrislerin determinantı gerekiyor. Bu recursive fonksiyonumuzda base call dediğimiz durum bizim için 2x2 durumudur. O kısma geldiği zaman a*d-b*c yönteminden determinant hesaplamasını yapabiliriz. Bu kısımda global pointer saklayan dizimizin görevide biraz değişiyor aslında. İlk matriste 4x4 lük matrisin determinantını aldığımızı düşünelim. Bunun pointeri dizimizin ilk elemanı oluyor. Sonraki 3x3 lüğün pointeri ise 2.eleman oluyor. Birden fazla 3x3 lük oluşuyor ancak bir sonrakine sıra geldiğinde ilkinin işi bitiyor, o yüzden ikinci 3x3lük matris birincinin üstüne yazılıyor. Sonra 3x3 lük için hesaplama yaparken 2x2 lik matris için de bir pointer gerekiyor. Bu da global matrix dizisinin sonraki elemanı oluyor. 5x5 kadar denedim sorun yok. Çok büyük matrisler için int** matrix[5] kısmındaki 5 değerini değiştirmeniz gerekecektir.

// Kullanıcının yapacağı işleme göre matris boyutlarının bazı kurallara uyması gerekiyor. Mesela determinant için kare matris olmalı, çarpımın yapılabilmesi için birincinin sütun sayısı ile ikincinin satir sayisi eşit olmalı gibi. Bu denetlemeleri matrislerin değerlerini de aldıktan sonra yapmak zorunda kaldım :)

// Toplama, çıkarma, sabit ile çarpma, transpoze alma işlemlerinden pek bahsetmeye gerek yok. Kağıt üzerinde olduğu gibi kodlaması da kolay.

Kodlama

Kaynak kod içerisinde de çok fazla yorum satırı var. Onlara da göz atmalısınız bence.

Kullanılan C dili yapıları:

Kaynak Kod

Ekran Görüntüleri

Yapılabilecekler

// Matrisi bir sabit sayıya böldüğümüzde sonuç matrisinin elemanları tam sayı olmayabilir. Bunun için bir şeyler yapılabilir. Matrisi sabit bir sayıya bölme işlemini eklemek istiyorsak.

// Determinant hesaplanırken direkt 1.satıra göre aldım. Ancak kağıt üzerinde yaptığımız gibi sıfırın fazla olduğu satırdan veya sütundan determinant alınabilir. 0 olan kısımlar için işlem yapılmaz. Ama sıfırları hesaplamak için harcayacağımız kaynak yerine direkt hesaplamayı yapmış olsak, arada ne gibi bir fark olabilir acaba?

// İşlemleri yapmak için matris boyutlarında uyuşmazlık durumu matrislerin elemanları alındıktan sonra yapılıyor. Bunun için daha etkili bir şeyler yapılabilir. Çünkü gereksiz işlem yapmış oluyoruz.

// Main’deki while döngüsünün başında bütün pointerlar free fonksiyonuna gönderiyor. Ancak matris boyutlarında uyuşmazlık nedeniyle o döngünün baştan başlatılması üst üste free yapılmasından dolayı hata verebiliyor.

// Fonksiyonları kullanarak sonraki eklemeleri kolaylaştırmaya çalıştım. O yüzden programın işleyişi anlaşılırsa başka matris işlemleri de kolayca programa dahil edilebilir.

// Bu programda matrislerimizin tamamen global şekilde ulaşılması fonksiyonlarımızın direkt c/p yapılıp başka programlarda kullanılmasını engelliyor. Global değişkenlerin fonksiyonların içerisinde kullanılması fonksiyonu bir kere yaz sonra başka yerde kullan durumuna aykırı olmuş.

Yorum ve eleştirileriniz varsa lütfen yazın.

İyi çalışmalar.