C Programlama Dili & Pointer

Başlatan yldzelektronik, 16 Eylül 2013, 09:23:31

yldzelektronik

https://www.picproje.org/index.php/topic,35908.msg365108.html#msg365108

Cevabında belirtildiği üzere ayrı başlıklarda olması bence de güzel fikir.Ancak forumda değişik ve dağınık başlıklarda bir çok kez pointer konusu açılmış.Toplu olması dileğiyle bu başlığı açıyorum.Umarım ilgilenen çıkar.Bu arada diğer konular da buraya alıntı yapılabilir.

Alıntı yapılan: CoşkuN - 16 Eylül 2013, 09:13:38
Bu konu altında oldukça faydalı tartışmalar oluyor ancak tek bir konu başlığı altında olması takibi zorlaştırıyor.
Bu mesajın altına açılan yeni konular farklı adlarla C programlama bölümü adı altında açılsa daha faydalı olacağını düşünüyorum.



Sorum halen açıklama bekliyor;
Şimdi *ptr ile oluşturduk.

*ptr = &value ile float value nin bellekteki adresini yazdık.Yani daha valuenin değeriyle ilgilenmedik.Doğru mu?

Eğer böyle ise şöyle bir şey oluyor.Benim elimde ptr içinde duran bir adres var ve bu adres sıralı 4 byte ile float bir sayı taşıyor.Peki ben o adresteki değeri ptr ile nasıl görücem?

write_eeprom(adres,*prt); ile ben parametre olarak valuenin adresinin ilk bytenı geçtim?

Şöyle;

float value = 123.123; // Bellekte 0x00 adresinde.
int *ptr = &value; //ptrnin içinde 0x00 oldu.

Ben herhangi bir yere *ptr olarak geçersem 0x00 adresinin ilk byte olarak taşıdığı değere erişiyorum.Yani 123.123 4 bytelık sayısının ilk bytena eriştim.Doğru mu?

Yani o zaman şu oluyor;
*ptr ile
ptr kullanımı fark ediyor. Doğru mu?

Bir yere *ptr olarak geçersem adresin taşıdığı değere, ptr olarak geçersem o adrese yani buradaki 0x00 a erişirim.Doğru mu?

Teşekkürler.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

kantirici


berat23

Alıntı YapYani o zaman şu oluyor;
*ptr ile
ptr kullanımı fark ediyor. Doğru mu?

Bir yere *ptr olarak geçersem adresin taşıdığı değere, ptr olarak geçersem o adrese yani buradaki 0x00 a erişirim.Doğru mu?

evet

yamak

Alıntı yapılan: yldzelektronik - 16 Eylül 2013, 09:23:31
https://www.picproje.org/index.php/topic,35908.msg365108.html#msg365108

Cevabında belirtildiği üzere ayrı başlıklarda olması bence de güzel fikir.Ancak forumda değişik ve dağınık başlıklarda bir çok kez pointer konusu açılmış.Toplu olması dileğiyle bu başlığı açıyorum.Umarım ilgilenen çıkar.Bu arada diğer konular da buraya alıntı yapılabilir.



Sorum halen açıklama bekliyor;
Şimdi *ptr ile oluşturduk.

*ptr = &value ile float value nin bellekteki adresini yazdık.Yani daha valuenin değeriyle ilgilenmedik.Doğru mu?

Eğer böyle ise şöyle bir şey oluyor.Benim elimde ptr içinde duran bir adres var ve bu adres sıralı 4 byte ile float bir sayı taşıyor.Peki ben o adresteki değeri ptr ile nasıl görücem?

write_eeprom(adres,*prt); ile ben parametre olarak valuenin adresinin ilk bytenı geçtim?

Şöyle;

float value = 123.123; // Bellekte 0x00 adresinde.
int *ptr = &value; //ptrnin içinde 0x00 oldu.

Ben herhangi bir yere *ptr olarak geçersem 0x00 adresinin ilk byte olarak taşıdığı değere erişiyorum.Yani 123.123 4 bytelık sayısının ilk bytena eriştim.Doğru mu?

Yani o zaman şu oluyor;
*ptr ile
ptr kullanımı fark ediyor. Doğru mu?

Bir yere *ptr olarak geçersem adresin taşıdığı değere, ptr olarak geçersem o adrese yani buradaki 0x00 a erişirim.Doğru mu?

Teşekkürler.
İlk olarak
*ptr=&value
değil
ptr=&value
olması gerekiyor.Çünkü burda ptr adres,*ptr ise o adresin içindeki veri oluyor.&value da value'nun adresi olduğu için ptr=&value olmalı.

Sorunuza gelecek olursak.Bu durum pointer türü ile alakalı bir durum.Örneğin
unsigned char f[]={1,2,5,1,23,5,6};
unsigned int i;

gibi bir dizim ve değişkenim olsun.
eğer

Ben eğer aşağıdaki gibi yaparsam.
i=*(unsigned int*)f;

dersem i'nin değeri 1+2*2^8+5*2^16+1*2^32 çıkar çünkü f'i tip dönüştürme ile unsigned int* türünden bir adrese dönüştürdük ve unsigned int de 4 byte yer kapladığı için f adresinin ilk 4 byte ını i'ye yüklemiş olduk.
Eğer
i=*(unsigned char*)f;

yaparsak i'nin değeri 1 olur.Çünkü bu sefer de ilk 1 byte almış olduk.

coderun

float value = 123.123; // float türünde bir değişken tanımlandı ve 123.123 değeri atandı
Kullanılacak pointer hangi tür değişkenlerin (int, float, char) adresini alacaksa o tür pointer tanımlanmalı.
Yukarıdaki value değileni float turunde olduğundan pointer float olmalı. Yani pointer tanımlaması şu şekilde olmalı


float *ptr; //float pointer tanımlandı
ptr=&value;// value nin adresi pointere yüklendi

Eğer program içinde (*ptr) şeklinde kullanırsak pointerin tuttuğu adresteki değere ulaşırız.
Eğer program içinde ptr şeklinde kullanırsak pointerin taşıdığı adrese ulaşırız

float z; olsun z= *ptr; // z ye ptr nin taşıdığı adresteki değer atandı
printf("Pointerin bulunduğu adresteki değer %f ", *ptr); printf ile pointerin bulunduğu adresteki değer gönderildi;
printf("Pointerin bulunduğu adres değeri %x", ptr); printf ile pointerin bulunduğu adres gönderildi.


char *c;// char 1 byte olsun
int *i;   // int 2 byte olsu
float *f;// float 4 byte olsun
Bu üç tür pointerlerin birbirinden farklarına bakalım. Genel olarak hepsi pointer desekte tuttukları adres değerleri farklı olacaktır. Yani char türünde olan *c pointerinin tuttuğu adres 1 byte lik değer taşırken int türünde olan *i pointeri 2 byte lık değer taşıyan bir adresi tutacaktır.
Bu şu kısımda önemli olmaktadır.(örnek üzerinden bakalım)

char karakter=35;// karakter değişkenin adreside 0x1234 olsun
int tamsayi=66;  //tamsayi değişkenin adresi 0x5678 olsun
float devirli=666.666;  //float değişkenin adresi 0x1020 olsun

c=&karakter;// c char pointerine karakterin adresi yüklendi (0x1234)
i=&tamsayi;// i int pointerine tamsayinin adresi yüklendi (0x5678)
f=&devirli;// f float pointerine devirlinin adresi yüklendi (0x1020)

Tüm bunlardan sora (c++;), (i++;), (f++;) ile pointerlerin adres değerlerini bir arttıralım.
Bu işlemden sora pointerlerin yeni adreslerine bakarsak her birinin artış miktarı farklı olduğunu görürüz.
char 1 byte değer taşıdığından char *c pointerinin adres artışı 1 olur ve yeni adresi 0x1235 olur.
int 2 byte değer taşıdığından int *i pointerinin adres artışı 2 olur ve yeni adresi 0x567A olur
float 4 byte değer taşıdığından  float *f pointerinin adres artışı 4 olur ve yeni adresi 0x1024 olur.

Yani formü edilmiş kısmı: adres artışı = sizeof(tip); (tip char, int, float... olabilir.)
(ptr++) ile yeni adres= birönceki adres + sizeof(tip);


int yine 2 byte olsun ve
int dizi[10];
int *i;
char *c;

i=dizi;// A işlemi
i=&dizi[0];// B işlemi

yukarıdaki A ve B işlemleri aynı işi yapmaktadır. eğer bir dizinin başlangıç adresleri bir pointere atamak için yukarıdaki iki işlemden biri yapılabilinir. Eğer direk dizi ismi ile diznin başlangıç adresi atanırken & adres operatörü kullanılmaz.

Yukarıda bahsettiğimiz pointer adres artışının etkisini burada direk görebiliriz;

i=dizi;//dizinin ilk elemanın adresi i pointerine verildi yani dizi[0] adresi alındı. adres değeri 0x1234 olsun
i++; // işlemi ile i nin adres değeri kendi türüne göre arttırıldı. int 2 byte olduğundan 2 birim artış ile i nin yeni adres değeri 0x1236
ve bu yeni adres ayrıca dizi[1] değişkenine aittir.
yani dizinin bir sonraki elemanının adresine ulaştık. bu sayede bir pointer ile dizinin istenilen elemanlarına ulaşıp, o elemana istenilen deger ataması yapılabilinir. bu özellikle bir fonk. dizi değişkenini yollamak gerektiğinde işe yarıyor. bir fonk bir diziyi komple yollayacağımıza o dizinin ilk adresini yollamamız yeterli olur. fonk içinde dizinin tüm elemanlarına pointer ile rahatlıkla ulaşırız.

Yukarıdaki int dizi[10]; değişkenin int olduğu için pointer int olarak tanımlandı. Peki pointer int değilde char olsaydı ve
c=dizi;// başlangıç adresi 0x1234
c++;// yeni adresi ?

yldzelektronik

Alıntı Yap
Yukarıdaki int dizi[10]; değişkenin int olduğu için pointer int olarak tanımlandı. Peki pointer int değilde char olsaydı ve
c=dizi;// başlangıç adresi 0x1234
c++;// yeni adresi ?

pointer char olarak tanımlansaydı (yani c bir byte alan kapasitesine sahip olsaydı) bir byte artacaktı ve dizinin ilk elemanının sekiz bitlik ksmına işaret edecekti.Yani 0x1235 olurdu.Ancak burada şu sorun olmuyor mu?

0x1234 değeri zaten bir byte dan daha büyük.Peki bu durumda c değeri ne olacak?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

mir_as82

tam emin olmamakla birlikte, burada iki olasılık var.
1-compiler hata mesajı verebilir.
2-Arkadaşın dediği gibi adres 0x1235 olabilir.

Ama aklıma bu sefer şu soru gelecek. Bu sefer adresin içindeki int türünden değişkeni char tipinden pointere nasıl yükleyeceğiz? Hata vermez mi compiler?  2 byte lık değişkeni tek byte lık char tipinin içine nasıl yerleştirecek.

yldzelektronik

Alıntı yapılan: mir_as82 - 16 Eylül 2013, 12:16:12
...
Ama aklıma bu sefer şu soru gelecek. Bu sefer adresin içindeki int türünden değişkeni char tipinden pointere nasıl yükleyeceğiz? Hata vermez mi compiler?  2 byte lık değişkeni tek byte lık char tipinin içine nasıl yerleştirecek.

Ben ccs için söylüyorum;
Type Casting deniyor sanırım bu işleme.Tip dönüştürme yaparken hata vermiyor.Yani int16 bir değişkeni int8 e aktarırken herhangi bir hata vermiyor ancak işlem yaparken sonuçlar sıkıntılı oluyor.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

rree

Adres uzunluğu pic serisine bağlı olması gerekir. Pic18Fxx ise 16 bit adres,   pic16fxx ise 14 bit(2byte). Pointer hangi türe seçersek seçelim adresden bahsediliyorsa  pic   mimarisine bağlı olarak adres uzunluğu aynı olması gerekir.