Upload
others
View
10
Download
0
Embed Size (px)
Citation preview
5. Hafta – Pointer (devam)
Dr. Öğr. Üyesi Nesibe YALÇIN
https://nesibeyalcin.wordpress.com/bsm104/
BARTIN ÜNİVERSİTESİ
MÜHENDİSLİK, MİMARLIK VE TASARIM FAKÜLTESİ
BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ
2
Void Pointer
― Void pointer, herhangi bir veri tipine ait değildir.
void * p;
― Void pointer, genel pointer/gösterici olarak ta tanımlanır.
― Adres saklama/yedekleme işlemlerinde kullanılır.
3
Void Pointer
#include <stdio.h>
#include <conio.h>
int main(){
int a=3;
void *p;
p=&a;
printf("a=%d, adresi: %p",a,p);
getch ();
}
4
Void Pointer
― Void pointer üzerinde aritmetik işlemler uygulanamaz. Void pointerın türü olmadığı için bu durumda adres değerinin ne kadar artacağı/azalacağı bilinemez.
― int a=3; ― void *ptr=&x; ― ptr++; //geçersiz ― ptr=ptr-2; //geçersiz ― --ptr; //geçersiz ― ptr+=1; //geçersiz
5
Void Pointer
― Void türden pointerlarda * ya da [ ] işleçleri geçersizdir. ― Bu işleçler bir veriye erişmek için tür bilgisine gereksinim duyar.
double a=2.4; char ders[]=“robotik”; void * b; void *p; b=&a; p=ders; *b=2.4; // geçersiz *p=‘R’; //geçersiz p[0]=‘R’; //geçersiz
6
Void Pointer
― Void pointerların gösterdikleri verilere/değerlere erişmek için tür dönüşümü yapılmalıdır.
#include <stdio.h>
int main(){
char a='2';
void *p=&a;
printf("%p\n",p);
printf("%c",*(char *)p);
}
7
Void Pointer
#include <stdio.h>
int main(){
double a[]={2.0, -1.2, 3.4, 2.6, -0.3};
void *p=a;
printf("%p\n",p);
printf("%p\n",(double*)p+1);
printf("%.2f ", *(double*)p);
printf("%.2f ",*((double*)p+1));
printf("%.2f ",*((double*)p+2));
printf("%.2f ",*((double*)p+3));
printf("%.2f ",*((double*)p+4)); }
8
Pointerlarda Const Kullanımı
“const” tanımlanmış değişkenlerin değerleri program içerisinde değiştirilemezler.
1. Pointerın gösterdiği adresteki değer üzerinde değişiklik yapılamaz. Ancak pointerın tuttuğu adres değiştirilebilir.
float a=2.3, b=1.0; const float * ptr=&a; *ptr=-1.2; //hatalı ptr=&b;
9
Pointerlarda Const Kullanımı
2. Pointerın tuttuğu adres bilgisi değiştirilemez. Ancak adreste bulunan değer değiştirilebilir.
float a=2.3, b=1.0; float * const ptr=&a; *ptr=-1.2; ptr=&b; //hatalı
10
Pointerlarda Const Kullanımı
3. Pointerın tuttuğu adres bilgisi ve adreste bulunan değer değiştirilemez.
float a=2.3, b=1.0; const float * const ptr=&a; *ptr=-1.2; //hatalı ptr=&b; //hatalı
11
Fonksiyonlarda Pointer Kullanımı
#include <stdio.h>
void f(int a){
a=7;
}
int main(){
int s= 78;
printf("s=%d\n",s);
f(s);
printf("s=%d",s); }
#include <stdio.h>
void f(int *a){
*a=7; }
int main(){
int s= 78;
printf("s=%d\n",s);
f(&s);
printf("s=%d",s); }
Parametrenin fonksiyon içerisinde değiştirilebilmesini, yapılan işlemlerden etkilenebilmesini istiyorsak parametre pointer olarak tanımlanmalıdır.
12
Uygulama -1
#include <stdio.h>
#include <conio.h>
void degistir(int *a,int* b){
int gecici = *a;
*a=*b;
*b =gecici; }
int main(){
int s1= 78;
int s2= -12;
printf("s1=%d, s2=%d\n",s1,s2);
degistir(&s1,&s2);
printf("s1=%d, s2=%d",s1,s2);
getch (); }
13
Uygulama -2 #include <stdio.h>
#include <conio.h>
int topla(int *a,int N){
int toplam=0;
for(int i=0;i<N;i++)
toplam+=*(a+i);
//toplam+=a[i];
return toplam;
}
int main(){
int urun_adet[10];
for(int i=0;i<10;i++){
printf("%d.kutuda:",i+1);
scanf("%d",(urun_adet + i));
//scanf("%d",&urun_adet[i]);
}
printf("urunlerin toplami=%d",topla(urun_adet,10));
getch (); }
14
Uygulama -3 #include <stdio.h>
#include <conio.h>
int *fact(int x){
int sonuc=1;
for(int i=1;i<=x;i++)
sonuc*=i;
return &sonuc;
}
int main(){
int a;
int *p;
printf("Sayi gir:");
scanf("%d",&a);
p=fact(a);
printf("%d!=%d, adresi: %p",a,*p,p);
getch (); }
15
Uygulama -4
char * ters_cevir(char *a ){
int i = 0;
int j = strlen(a)-1;
while (i < j) {
char gecici = *(a+i);
*(a+i) = *(a+j);
*(a+j)= gecici;
i++;
j--;
}
return a; }
#include <stdio.h>
#include <conio.h>
#include <string.h>
char * ters_cevir(char a []){
int i = 0;
int j = strlen(a)-1;
while (i < j) {
char gecici = a[i];
a[i] = a[j];
a[j] = gecici;
i++;
j--; }
return a;
}
int main(){
char yazi[50];
gets(yazi);
printf("%s",ters_cevir(yazi));
getch (); }
16
Uygulama -5 #include <stdio.h>
#include <conio.h>
int max_bul(double *a, int N){
double max = a[0]; //max=*a;
int indis=0;
for(int i=1; i<N; i++)
if(a[i] > max) // if(*(a+i)>max)
{
max = a[i]; // max=*(a+i);
indis=i;
}
return indis; }
int main(){
double dizi[10]={2.6, -2, -5, 6.4, 8.8, 1, 4.8, 0.6, 4, 2.2};
int x=max_bul(dizi,10);
printf("En buyuk elemanin indisi:%d\n",x);
printf("En buyuk eleman:%.2f",dizi[x]);
//dizi[x]) --> *(dizi+i)
getch (); }
17
Fonksiyonlarda Pointer Kullanımı
― Fonksiyonlarda diğer değişkenler ve diziler gibi belleğe yüklenirler.
― Fonksiyonlarında bir başlangıç adresleri vardır. Dizilerde olduğu gibi fonksiyonun adı da fonksiyonun başlangıç adresini tutar.
18
Uygulama -6
#include <stdio.h>
#include <conio.h>
int bas_topla(int x){
int toplam=0,basamak_degeri;
int gecici = x;
while(gecici>0){
basamak_degeri= gecici%10;
toplam+=basamak_degeri;
gecici=gecici/10; }
return toplam; }
19
Uygulama -7
int main(){
int a;
do{
printf("Bir sayi giriniz:");
scanf("%d",&a);
}while(a<=0);
printf("Sayinin basamak degerleri
toplami:%d\n",bas_topla(a));
printf("Fonksiyon adresi:%p",bas_topla);
getch (); }
20
Fonksiyonlarda Pointer Kullanımı
― int (*pf)(int, int);
― Bu pointerı sadece iki adet int tipli parametre alan ve geriye int tipli bir değişken döndüren fonksiyonları gösterebilir.
― Örneğin; int alan_hesap(int a, int b) { ……. }
21
Uygulama -8
#include <stdio.h>
#include <conio.h>
int kupu_al(int a)
{
int sonuc=a*a*a;;
return sonuc;
}
int main(){
int s= 7;
printf("fonksiyonun adresi=%p\n",kupu_al);
printf("s' nin kupu=%d\n",kupu_al(s));
int (*p)(int);
p=kupu_al;
printf("fonksiyonun adresi=%p\n",p);
getch (); }
22
Uygulama -9
#include <stdio.h>
#include <conio.h>
int p_kupu_al(int *a)
{
int sonuc=(*a)*(*a)*(*a);
return sonuc;
}
int main(){
int s= 7;
printf("gosterici fonksiyonun adresi=%p\n",p_kupu_al);
printf("s' nin kupu=%d\n",p_kupu_al(&s));
int (*pf)(int*);
pf=p_kupu_al;
printf("gosterici fonksiyonun adresi=%p",pf);
getch (); }
23
Neden Pointer?
― Belleğin istenilen bir bölgesine doğrudan erişmek için
― Bir fonksiyonun birden fazla değer (dizi gibi) gönderebilmesi için
― Dinamik veri yapıları (yığın, kuyruk, bağlı liste, …) oluşturmak ve bunlar üzerinde değişiklik yapmak için
pointerlar kullanılır.
24
Void Pointer Fonksiyonları
― string.h kütüphanesinde yer alırlar: ― memcpy(void *ptr1, void *ptr2, int N)
• ptr2 adresinden başlayarak ptr1 adresine N sayıda byte'ı kopyalar. Aynı türden herhangi iki dizi yine bu fonksiyon yardımıyla kopyalanabilir. • Kopyalanacak bellek alanlarının üst üste gelme durumu varsa fonksiyon istenilen çıktıları üretememektedir.
― memmove(void *ptr1, void *ptr2, int N)
― Memcpy ile aynı görevi üstlenir. Daha güvenli bir kopyalama sağlar ama memcpy 'ye göre daha yavaştır.
25
Void Pointer Fonksiyonları
― mempcpy(void *ptr1, void *ptr2, int N) • Kopyalama işlemi yaptıktan sonra bir sonraki adresi geri dönüş olarak verir.
― memccpy(void *ptr1, void *ptr2, int a, int N)
• a değeriyle karşılaşıncaya kadar kopyalama yapar bulamazsa N byte’ lık alan kadar kopyalama yapar.
― memset(void *ptr, int a, int N)
• ptr adresinden başlayarak N byte’ lık alan a değeri ile doldurulur.
26
Void Pointer Fonksiyonları
― memchr(void *ptr, int a, int N) • ptr adresinden başlayarak N byte’ lık alanda a değerini arar. Bulduğunda a’ nın bulunduğu adresi (void türde), bulunmazsa NULL değerini döndürür.
― memcmp(void *ptr1, void *ptr2, int N) ― ptr1 ve ptr2 adreslerinden başlayarak N byte’ lık bir alandaki değerleri karşılaştırır. Eşitse 0, ptr1 adresindeki değer büyükse 1, küçükse -1 değerini döndürür.