Upload
chancellor-swanson
View
79
Download
0
Embed Size (px)
DESCRIPTION
BPR152 ALGORİTMA VE PROGRAMLAMA - II. Öğr . Gör. Bayram AKGÜL [email protected] http ://myo.bartin.edu.tr/akgul. Konular. F onksiyon Paramet releri ve Argum anlar Pass-by-value ref o ut Dizi parametreler Değişken sayıda parametre alan fonksiyonlar - PowerPoint PPT Presentation
Citation preview
BPR152 ALGORİTMA VE PROGRAMLAMA - II
Öğr. Gör. Bayram AKGÜ[email protected]
http://myo.bartin.edu.tr/akgul
2
• Fonksiyon Parametreleri ve Argumanlar– Pass-by-value– ref– out– Dizi parametreler– Değişken sayıda parametre alan fonksiyonlar
• Fonksiyonların aşırı yüklenmesi• Opsiyonel parametreler
Konular
3
Fonksiyon Parametreleri & Argumanlar
• Parametreler fonksiyon tanımlanırken fonksiyona dışarıdan gelen değişkenlerdir.– Parametreler fonksiyon tanımlanırken kullanılacak takma
isimlerdir.• Argumanlar fonksiyon çağrılırken kullanılan
ifadelerdir.// a, b ve c parametrelerdir static int Topla(int a, int b, int c){ return a + b + c;}
static void Main(){ int x = 2;
int y = Topla(x, 3, x * 2); // x, 3 ve x*2 argumanlardır }
Fonksiyon çağrılırken kullanılan argumanlar aşağıdakiler gibi olabilir: ― x― 3― x*2
4
Parametre & Argüman Türleri• C# ta, normal olarak kullanılan argümanlar
değerleri ile kullanılır (passed-by-value)– Fonksiyon çağrılırken tüm argümanlar
hesaplanıyor ve değerleri karşılık gelen parametreye aktarılıyor.
– Bu durumda Fonksiyon çalışması sırasında parametrenin değerinin değişmesi argümanın değerini etkilemez.
5
Değer olarak geçme (Pass-by-Value) static int Fnk(int a, int b, int c){ a += b + c; // a'nın değeri değişiyor return a;}
static void Main(){ int x = 2; int y = 3; int z = 4; int t = Fnk(x, y, z); Console.Write("x: {0}, y: {1}, z: {2}, t: {3}", x, y, z, t);}
x: 2, y: 3, z: 4, t: 9 x argümanı ‘a’ parametresi olarak fonksiyona geçiyor ve değeri değişmesine rağmen ‘x’ in değeri değişmiyor.
- Argümanların değerini değiştirmek mümkün mü?
6
Argümanların değerini fonksiyonda değiştirmek
static void Ayristir(double sayi, int tam, double ksr){ tam = (int)sayi; ksr = sayi - tam;}
static void Main(){ int i = 0; double f = 0.0;
Ayristir(2.35, i, f); Console.Write("Tam Kısım: {0}, kesir kisim:{1:F2}", i, f);}
• Ondalıklı bir sayının tam ve virgülden sonraki kısmını ayırıp ekrana yazdıran bir fonksiyon yazmak istiyoruz.– sayi = 2.35 tam kisim: 2, kesir kisim: 0.35– Muhtemelen bu işi yapacak fonksiyon (?)
Tam Kısım: 0, kesir kisim:0,00
7
Adres geçme (Pass-by-Ref)
static void Ayristir(double sayi, ref int tam, ref double ksr){ tam = (int)sayi; ksr = sayi - tam;}
static void Main(){ int i = 0; double f = 0.0;
Ayristir(2.35, ref i, ref f); Console.Write("Tam Kısım: {0}, kesir kisim:{1:F2}", i, f);}
• ref parametre: değişkenlerin metotlara adres gösterme yoluyla aktarılmasını sağlar.– ref sözcüğüyle bir değişkenin metoda adres gösterme yoluyla
aktarılabilmesi için ana programda değişkene bir ilk değer verilmelidir. Yoksa hata verir.
Tam Kısım: 2, kesir kisim:0,35
out parametre• Kullanımı ref anahtar sözcüğüyle tamamen
aynıdır. – Tek farkı out ile belirtilen değişkenlere esas
programda bir ilk değer verilmesinin zorunlu olmamasıdır.
– Örneğin aşağıdaki kullanım tamamen doğrudur:
8
static void Ayristir(double sayi, out int tam, out double ksr){ tam = (int)sayi; ksr = sayi - tam;}
static void Main(){ int i; double f;
Ayristir(2.35, out i, out f); Console.Write("Tam Kısım: {0}, kesir kisim:{1:F2}", i, f);}
ref & out • ref veya out anahtar sözcükleri ile
geçilen parametreler fonksiyonda değişirse değişim ana programa da yansır. – Çünkü değişkenlerin aslında adresleri
gönderilmiştir.
9
static int Fnk(ref int a, ref int b, ref int c){ a += b += c += 1; return a;}
static void Main(){ int x = 2, y = 3, z = 4;
int t = Fnk(ref x, ref y, ref z); Console.Write("x: {0}, y: {1}, z: {2}, t: {3}", x, y, z, t);}
x: 10, y: 8, z: 5, t: 10
Parametre olarak diziler
10
using System;class Program{ static void Yaz(int[] dizi) { foreach (int i in dizi) Console.WriteLine(i); }
static void Main() { int[] dizi = { 1, 2, 4, 7, 9 }; Yaz(dizi); }}
• Buradaki Yaz metodu kendisine parametre olarak verilen dizinin elemanlarını alt alta yazar.
• Bu fonksiyona gönderilen parametrenin int türünden dizi olması gerekir.
• Her hangi türden bir dizi göndermek istersek ne yapmalıyız?
Parametre olarak diziler
11
using System;class Program{ static void Yaz(Array dizi) { foreach (object i in dizi) Console.WriteLine(i); }
static void Main() { int[] dizi1 = { 1, 2, 4, 7}; double[] dizi2 = { 1.2, 3.4, 5.6}; string[] dizi3 = { "Sarı", "Kırmızı", "Mavi", "Yeşil" }; Yaz(dizi1); Yaz(dizi2); Yaz(dizi3); }}
• Buradaki Yaz metodu kendisine parametre olarak gönderilen herhangi bir dizinin elemanlarını alt alta yazar.
• Bu fonksiyona gönderilen parametrenin sadece dizi olması yeterlidir.
12471,23,45,6SarıKırmızıMaviYeşil
Dizi parametreleri• Dizi parametrelerinde yapılan bir
değişiklik gerçek diziyi etkiler. • Çünkü diziler parametre olarak
kullanıldığında dizinin kendisi yerine adresi gönderilir.
• Dolayısıyla aynı bellek bölgesi üzerinde işlem yapılır.
12
Parametre olarak diziler
13
using System;class Program{ static void EkranaYazdir(int[] dizi) { for (int i = 0; i < dizi.Length; i++) Console.Write(dizi[i] + " "); Console.WriteLine("\n"); }
static void ikiyeKatla(int[] dizi) { for (int i = 0; i < dizi.Length; i++) dizi[i] *= 2; }
static void Main() { int[] dizi = { 1, 2, 4, 7, 9 }; EkranaYazdir(dizi); // ilk halini yazdır ikiyeKatla(dizi); // dizi değişecek EkranaYazdir(dizi); // son halini yazdır }}
1 2 4 7 9
2 4 8 14 18
Fonksiyonların aşırı yüklenmesi
• C#'ta parametre sayısı ve/veya parametrelerin türleri farklı olmak şartıyla aynı isimli birden fazla fonksiyon oluşturulabilir. Buna fonksiyonların aşırı yüklenmesi denir.
14
static void EkranaYaz(string yazi){ Console.Write(yazi);}
static void EkranaYaz(int sayi, int sefer){ for (int i = 0; i < sefer; i++) Console.Write(sayi);}
• Farklı sayılarda ve türlerde parametrelerle aynı isimli fonksiyon!
Aşırı yüklenmiş Fonksiyonların Çağrılışı:
• C#, bir fonksiyon çağrıldığında ve çağrılanla aynı isimli birden fazla fonksiyon bulunduğunda fonksiyonun çağrılış biçimine bakar.
• Yani ana programdaki fonksiyonda girilen parametrelerle oluşturulmuş olan fonksiyonların parametrelerini kıyaslar. – Önce parametre sayısına bakar. – Eğer aynı isimli ve aynı sayıda parametreli birden
fazla metot varsa;– Bu sefer parametre türlerinde tam uyumluluk arar, – Parametre türlerinin tam uyumlu olduğu bir metot
bulamazsa;– Bilinçsiz tür dönüşümünün mümkün olduğu bir metot
arar,– Onu da bulamazsa programımız hata verir. 15
Aynı isimde fonksiyonlar! - 1
16
using System;class Metotlar{ static void Metot (int x, int y) { Console.WriteLine("1. metot çağrıldı."); } static void Metot(float x, float y) { Console.WriteLine("2. metot çağrıldı."); } static void Metot(string x, string y) { Console.WriteLine("3. metot çağrıldı."); } static void Main() { Metot("deneme", "deneme"); Metot(5, 6); Metot(10f, 56f); Console.ReadLine(); }}
3. metot çağrıldı.1. metot çağrıldı.2. metot çağrıldı.
• Bu programda üç metot da aynı sayıda parametre almış.
• Bu durumda parametrelerin türlerine bakılır:
• Ana programdaki Metot("deneme","deneme"); satırıyla üçüncü metot çağrılır.
• Metot(5,6); metot çağrımının parametre türlerinin tam uyumlu olduğu metot birinci metottur, o yüzden birinci metot çağrılır.
• Eğer birinci metot oluşturulmamış olsaydı ikinci metot çağrılacaktı.
• Son olarak Metot(10f,56f); satırıyla da ikinci metot çağrılır.
Aynı isimde fonksiyonlar! - 2
17
using System;class Metotlar{ static void Metot(float x, float y) { Console.WriteLine("1. metot çağrıldı."); }
static void Metot(double x, double y) { Console.WriteLine("2. metot çağrıldı."); }
static void Main() { Metot(5, 6); }}
1. metot çağrıldı.
• Bu programda iki metodun da parametre sayısı eşit, iki metotta da tam tür uyumu yok ve iki metotta da bilinçsiz tür dönüşümü mümkün.
• Bu durumda en az kapasiteli türlü metot çağrılır.
• Yani bu programda birinci metot çağrılır.
Aynı isimde fonksiyonlar! - 3
18
using System;class Metotlar{ static void Metot(float x, float y) { Console.WriteLine("1. metot çağrıldı."); }
static void Metot(int x, int y) { Console.WriteLine("2. metot çağrıldı."); }
static void Main() { Metot(5, 6.4f); }}
1. metot çağrıldı.
• Bu programda iki metodun da parametre sayısı eşit, iki metotta da tam tür uyumu yok!
• Parametrelerden bilinçsiz dönüşüm yapılabilecek fonksiyon çağırılır.
• Yani bu programda birinci metot çağrılır.
Aynı isimde fonksiyonlar! - 4
19
using System;class Metotlar{ static void Metot(float x, float y) { Console.WriteLine("1. metot çağrıldı."); }
static void Metot(int x, int y) { Console.WriteLine("2. metot çağrıldı."); }
static void Main() { Metot('f', 'g'); }}
2. metot çağrıldı.
• Bu programda iki metodun da parametre sayısı eşit, iki metotta da tam tür uyumu yok!
• Parametrelerden bilinçsiz dönüşüm yapılabilecek fonksiyon çağırılır. char hem inte hem de floata bilinçsiz olarak dönüşebilir. Ancak int daha az kapasiteli olduğu için birinci metod çağırılır.
Değişken sayıda parametre alan Fonksiyonlar
• Şimdiye kadar fonksiyonlarımıza gönderdiğimiz parametre sayısı belliydi ve bu parametre sayısından farklı miktarda parametre girersek programımız hata veriyordu.
• İstediğimiz sayıda parametre girebileceğimiz fonksiyonlar yazabilir miyiz?
int t1 = Toplam(5,10); int t2 = Toplam(7,12,45);int t3 = Toplam(123, 12, 5, 7, 9, 4, 12);
20
Değişken sayıda parametre
21
static int Toplam(params int[] sayilar){ if (sayilar.Length == 0) return 0;
int toplam = 0; foreach (int i in sayilar) toplam += i;
return toplam;}
static void Main(){ Console.WriteLine(Toplam()); Console.WriteLine(Toplam(5)); Console.WriteLine(Toplam(5, 10)); Console.WriteLine(Toplam(2, 9, 12)); Console.WriteLine(Toplam(7, 12, 45)); Console.WriteLine(Toplam(123, 12, 5, 7, 9, 4, 12));}
05152364172
Opsiyonel parametreler• Bir fonksiyonun birden fazla amaç için
kullanılmasını sağlayabiliriz. • İsteğe bağlı parametreler kullanarak bu
durumu sağlayabiliriz.
• Örnek: Aşağıdaki üç fonksiyonu düşünelim:• static double TutarHesapla(double fiyat, int adet)• static double TutarHesapla(double fiyat, int adet, bool kdv)• static double TutarHesapla(double fiyat, int adet, bool kdv, double
kdv_orani)
–Bu üç fonksiyonu aşırı yükleyerek gelecek slayttaki gibi yapabiliriz.
22
Opsiyonel Parametreler
23
static double TutarHesapla(double fiyat, int adet){ return fiyat * adet;}
static double TutarHesapla(double fiyat, int adet, bool kdv){ double tutar = fiyat * adet; if (kdv) tutar *= (1.18); return tutar;}
static double TutarHesapla(double fiyat, int adet, bool kdv, double kdv_orani){ double tutar = fiyat * adet; if (kdv) tutar *= (1 + kdv_orani); return tutar;}
static void Main(){ double t1 = TutarHesapla(100, 2); double t2 = TutarHesapla(100, 2, true); double t3 = TutarHesapla(100, 2, true, 0.08);
Console.WriteLine("Tutar-1:{0} TL, Tutar-2:{1} TL, Tutar-3:{2} TL", t1, t2, t3);}
Tutar-1:200 TL, Tutar-2:236 TL, Tutar-3:216 TL
Opsiyonel Parametreler
24
static double TutarHesapla(double fiyat, int adet){ … }
static double TutarHesapla(double fiyat, int adet, bool kdv) { … }
static double TutarHesapla(double fiyat, int adet, bool kdv, double kdv_orani){ … }
static void Main(){ double t1 = TutarHesapla(100, 2); double t2 = TutarHesapla(100, 2, true); double t3 = TutarHesapla(100, 2, true, 0.08);
Console.WriteLine("Tutar-1:{0} TL, Tutar-2:{1} TL, Tutar-3:{2} TL", t1, t2, t3);}
• Fonksiyon ilk çağırılışta iki parametreli fonksiyon çalışacaktır.• İkinci çağırılışta üç parametreli fonksiyon çalışacaktır.• Üçüncü çağırılışta ise dört parametreli fonksiyon çalışacaktır.
Opsiyonel Parametreler
25
public double TutarHesapla(double fiyat, int adet, bool kdv=false, double kdv_orani=0.18 ){ double tutar = fiyat * adet; if (kdv) tutar *= (1 + kdv_orani); return tutar;}
static void Main(){ double t1 = TutarHesapla(100, 2); double t2 = TutarHesapla(100, 2, true); double t3 = TutarHesapla(100, 2, true, 0.08);
Console.WriteLine("Tutar-1:{0} TL, Tutar-2:{1} TL, Tutar-3:{2} TL", t1, t2, t3);}
Tutar-1:200 TL, Tutar-2:236 TL, Tutar-3:216 TL
Opsiyonel Parametreler: Eğer fonksiyon iki parametre ile çağırılırsa kdv’nin değeri false ve kdv_oranı 0.18 olacaktır. Eğer fonksiyon üç parametre ile çağırılırsa yine kdv_oranı 0.18 olacaktır.
• Fonksiyonu üç defa yazmaktansa varsayılan parametreler ile aşağıdaki gibi bir defa yazabiliriz.
• Bu fonksiyon önceki üç fonksiyonun da işini görür!
Opsiyonel Parametreler Üzerine Notlar
• ref veya out parametreler opsiyonel olarak tanımlanamaz!
• Opsiyonel parametreler tüm parametrelerin en sağında olmak zorundadır, normal parametreler arasında opsiyonel parametreler tanımlanamaz!
• Bir fonksiyonda hepsi en sağda tanımlanmak şartı ile birden fazla opsiyonel parametre olabilir.
• Opsiyonel parametrelerden bazılarına değer geçerek bazılarına ise değer geçmeden kullanmak istiyorsanız değer geçeceğiniz parametreler solda olmak zorundadır!
– Örneğin önceki sılaytta hazırladığımız TutarHesapla fonksiyonunu aşağıdaki gibi kullanamazsınız!
double t = TutarHesapla(100, 2, 0.08); // ERROR!26
Opsiyonel Parametre - İşlem
27
static double Hesapla(double x, double y, char islem = '+'){ switch (islem) { case '+': return x + y; case '-': return x - y; case '*': return x * y; case '/': return x / y; case '%': return x % y; default: return 0; }}
static void Main(){ Console.WriteLine(Hesapla(5, 3)); Console.WriteLine(Hesapla(5, 3, '+')); Console.WriteLine(Hesapla(5, 3, '-')); Console.WriteLine(Hesapla(5, 3, '*')); Console.WriteLine(Hesapla(5, 3, '/')); Console.WriteLine(Hesapla(5, 3, '%')); Console.WriteLine(Hesapla(5, 3, '^'));}
882151,6666666666666720
DİNLEDİĞİNİZ İÇİN TEŞEKKÜRLER…
Öğr. Gör. Bayram AKGÜL 28