Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

* pointer

Başlatan hasankomur, 13 Aralık 2012, 12:43:00

hasankomur

Elimdeki bir diziyi bir fonksiyon da işlemek istiyorum. Ve bunu pointer kullanarak yapmaya çalıştım. Program hata vermedi fakat dizi deki değerleri değil de farklı değerleri işliyor. Program çok uzun sadece pointer ı nasıl kullandığımı yazıyorum.


int kup1={0xC3,0x60,0xC3};

void kup(int *dizi){
...
output_b(dizi[0]);
...
...
}

kup(&kup1);     



Kazım

#1
Bu linkte birçok gösterici örneği var.Okumanı tavsiye ederim.

http://www1.gantep.edu.tr/~bingul/c/index.php?ders=11

output_b(dizi[0]);

deyince sanırım B portuna dizini 0 indexli elemanın yerleştirmek istiyorsun ancak - değerini değil adresini yerleştirmişsin.Birde emin değilim ama pointerei dizi olarak kullanırken dizi[0] doğru değil diye biliyorum. Aslında ponterlerin boyutları olmuyor . Sadece sıralı bir şekilde elemnın değerlerini işaret eder -ve bizde adresleri arttırarak değerlere ulaşıyoruz.Ben proteus simulasyonlarından anladığım kadarıyla böyle oluyor.Yanlışım varsa usta arkadaşlar düzeltebilir..


output_b(*dizi);       pointer ilk adresindeki değer

dizi++;          adresi 1 arttırıyoruz

output_b(*dizi);        ve sonraki değeri  -> gibi kullanacaksın



fgokcegoz

#2
int kup1={0xC3,0x60,0xC3};


Dizi tanımlamada hata var. Aşağıdaki şekilde olmalı.

int kup1[3]={0xC3,0x60,0xC3};



Birde fonksiyona adres gönderirken yanlış göndermişsiniz..
kup(&kup1); 
olarak değilde,
kup(kup1); 
veya
kup(&kup1[0]); 


Çünkü dizilerin isimleri aslında birer adres belirtirler. Kendi isimlerini gönderdiğinizde, adres göndermiş olursunuz. Veyahutta dizinin ilk elemanının adresinide gönderebilirsiniz. Aynı anlama gelir.
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

Kazım

#3
sayın @gokcegoz ; yada diğer &arkadaşlar ;
Benim aklıma takılan bir şey var onu sormak istiyorum size ;

8bitlık işlemcilerde int için 4 byte yer ayrılıyor ve biz ilgili değişkenin değerine ilk başlangıç adresini göstererek değere ulaşıyoruz.Ancak sonraki değer için neden adresi 1 arttırıyoruz. neden 4 arttırmıyoruz ?? dizinin 2. indeksindeki verinin adresi 4 byte sonrasındaki adres olmaz mı ? Yoksa pointeri int tanımlama yaptığımız için mi 4 byte artar ? Böylelikle doğru adrese ulaşırız ???  AŞağıdaki tarifi soruyorum yani ;

C dilinde göstericiler ve diziler arasında yakın bir ilişki vardır. Bir dizinin adı, dizinin ilk elemanının adresini saklayan bir göstericidir. Bu yüzden, bir dizinin herhangi bir elemanına gösterici ile de erişilebilir. Örneğin:

          int kutle[5], *p, *q;

şeklinde bir bildirim yapılsın. Buna göre aşağıda yapılan atamalar geçerlidir:

          p = &kutle[0];    /* birinci elemanın  adresi p göstericisne atandı */
          p = kutle;        /* birinci elemanın  adresi p göstericisne atandı */
          q = &kutle[4];    /* son      elemanın adresi q göstericisne atandı */

İlk iki satırdaki atamalar aynı anlamdadır. Dizi adı bir gösterici olduğu için, doğrudan aynı tipteki bir göstericiye atanabilir. Ayrıca, i bir tamsayı olmak üzere,

          kutle;

ile
          *(p+i);

aynı anlamdadır. Bunun sebebi, p göstericisi kutle dizisinin başlangıç adresini tutmuş olmasıdır. p+i işlemi ile i+1. elemanın adresi, ve *(p+i) ile de bu adresteki değer hesaplanır

Klein

8 bit işlemcilerde int genellikle 2 byte uzunluğundadır.

Evet pointeri de int tanımladığımız için 1 yerine 2 (veya 4) bayt artar. 

Kazım

Klein ustam çok saol ...

Mesajı editledim siz cevap yazmadan önce, ama mesajlarımı uzatmamın nedeni, yalnız kendimin değil okuyan diğer arkadşların da konuyu kavramasıdır.. Tekrar teşekkür ederim

fgokcegoz

unsigned char x[6]; gibi bir char dizimiz olsun.



unsigned char * pnt_char;
pnt_char =(unsigned char *)x;    olarak tanımlanmış, yukarıdaki x dizisinin elemanlarını point eden bir pointer ımız olsun.

pnt_char++ dediğimizde birer birer artırır. Çünkü göstericimizin point ettiği char tipindeki dizinin her elemanı bir byte yer kaplar.




unsigned int y[3]; gibi bir integer dizimiz olsun.



unsigned int * pnt_int;
pnt_int =(unsigned int *)y; olarak tanımlanmış, yukarıdaki y dizisinin elemanlarını point eden bir pointer ımız olsun.

pnt_int++ dediğimizde ikişer ikişer artırır. Çünkü göstericimizin point ettiği int tipindeki dizinin her elemanı iki byte yer kaplar.




"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

JKramer

Diziyi tanımlarken değerleri yazarsanız, boyutunu belirtmeseniz de olur:
int kup1[]={0xC3,0x60,0xC3};


fgokcegoz

Alıntı yapılan: JKramer - 13 Aralık 2012, 15:35:04
Diziyi tanımlarken değerleri yazarsanız, boyutunu belirtmeseniz de olur:
int kup1[]={0xC3,0x60,0xC3};


Tabiki olur. Eğer 3 elemanlı bir diziyi bu şekilde tanımladıktan sonra yani eğer boyutunu belirtmezseniz sonradan 4. bir eleman ekleyebilirsiniz. Burada bir mantık hatası oluşmaz. Ama diziyi 3 elemanlı olarak belirttikten sonra dizinin boyutu kesindir. Siz ilk ikisi için başlangıç değeri atasanız bile 3.sü içinde yer ayırır. Bu durumda boyut belirtmezseniz, sınırlar kesin olamayacağından bazı durumlarda mantık hatası olabilir. Bu nedenle dizinin boyutunu belirtmekte fayda olduğunu düşünüyorum. 
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

hasankomur

Cevaplarınız için teşekkürler. Önerilerinizin hepsini uyguladım fakat istediğim değeri göremiyorum farklı farklı değerler alıyorum.

Ayrıca kup(kup1) deyimini kabul etmiyor hata veriyor program. kup(&kup1) şeklinde olması gerekiyor.

JOKERAS

Selam,
Sizin tanımladığınız dizi int türden içine yerleştirdiğiniz değerler
char türden yani dizi tipiniz 16bit iken siz 8 bit değer yerleştirmişsiniz.
Dizi içeriği bellekte şu şekilde olur,tabii bu derleyiciye göre değişebilir little endian
big endian gibi,bazı derleyicilerde bu ayarlar olabiliyor.

index0 ->   dizi[0] H = 00  çöp,rastgele değer
                  dizi[0] L = C3

index1 ->   dizi[1] H = 00  çöp,rastgele değer
                  dizi[1] L = C6

index2 ->  dizi[2] H = 00  çöp,rastgele değer
                dizi[2] L = C3

Siz kup adlı fonksiyona bu dizinin adresini geçtiğinizde dolayısı ile
dizinin içiresindeki çöp rastgele değerleri görürsünüz.
Diziyi bir arttırdığınızda pointer 2byte olduğu için 2 byte artar.

kup1 adlı dizi'nizi ve fonksiyon parametresini char olarak değiştirin ve
fonksiyonu çağırdığınızda kup1 adlı dizinin adresini alıp geçirmeyin adını geçirmeniz yeterli.

Yani şöyle;

   char kup1[] = {0xc3, 0xc6, 0x c3};

   void kup (char *p) {
         char idx = 0;
         output_b(p+idx);
         veya
         output_b(p[idx]);
         idx++;
    }
   while(1) {
          kup(kup1);
   }
   
Bu şekilde bir deneyin.

hasankomur

#11
Alıntı yapılan: JOKERAS - 13 Aralık 2012, 20:02:05
Selam,
Sizin tanımladığınız dizi int türden içine yerleştirdiğiniz değerler
char türden yani dizi tipiniz 16bit iken siz 8 bit değer yerleştirmişsiniz.
Dizi içeriği bellekte şu şekilde olur,tabii bu derleyiciye göre değişebilir little endian
big endian gibi,bazı derleyicilerde bu ayarlar olabiliyor.

index0 ->   dizi[0] H = 00  çöp,rastgele değer
                  dizi[0] L = C3

index1 ->   dizi[1] H = 00  çöp,rastgele değer
                  dizi[1] L = C6

index2 ->  dizi[2] H = 00  çöp,rastgele değer
                dizi[2] L = C3

Siz kup adlı fonksiyona bu dizinin adresini geçtiğinizde dolayısı ile
dizinin içiresindeki çöp rastgele değerleri görürsünüz.
Diziyi bir arttırdığınızda pointer 2byte olduğu için 2 byte artar.

kup1 adlı dizi'nizi ve fonksiyon parametresini char olarak değiştirin ve
fonksiyonu çağırdığınızda kup1 adlı dizinin adresini alıp geçirmeyin adını geçirmeniz yeterli.

Yani şöyle;

   char kup1[] = {0xc3, 0xc6, 0x c3};

   void kup (char *p) {
         char idx = 0;
         output_b(p+idx);
         veya
         output_b(p[idx]);
         idx++;
    }
   while(1) {
          kup(kup1);
   }
   
Bu şekilde bir deneyin.

Bu da işe yaramıyor. Ve kup(kup1) yazınca hata veriyor

mesaj birleştirme:: 13 Aralık 2012, 20:33:13

Program bu şekilde çalışıyor fakat benim yapmak istediğim değerleri dizi içine atmak ve farklı değerleri de kullanma. Pointer geldi aklıma onuda uygulayamadım

...

void kup(){
  while(a<3){
  for(k=0;k<30;k++){
   for(i=a;i<b;i++){
   for(j=0;j<250;j++){
   output_a(kat);
   switch(b){
   case 2:
          output_b(0xC3);     
          delay_us(1);
          break;
   case 3:
       
          output_b(0x60);
          output_d(0x60);
          delay_us(1);
          break;
   case 4:
         
          output_d(0xC3);
          delay_us(1);
          break;
   }
   }
   }
   sifirla();
   }
   a++;
   b++;
  }
  a=0;
  b=2;
}

...

kup();
...

justice_for_all

gonderdigin kodda dizin icinde herhangi bir degisiklik yapmamissin ama.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

hasankomur

Evet bu ilk yazdığım kod. Bir diziye atmak istedim. Ve pointer kullanmaya çalıştım.

justice_for_all

char kup1[3] ;
void kup (char *p)
  {
       *p++=1;
       *p++=2;
       *p++=3;
    }

    kup(&kup1); //veya  kup(&kup1[0]);
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay