Picproje Elektronik Sitesi

DERLEYİCİLER => Diğer Derleyiciler => Konuyu başlatan: Klein - 07 Şubat 2012, 19:23:18

Başlık: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 19:23:18
int x;
int *y;

y =  &x

y?

y nin gösterdiği adresi bir değişkene atmayı başaramadım. Gösterilen adresin içeriğini değil. Adresin kendisini. yani y nin içeriğini.
Bütün kitaplar ve örnekler adresi göstermek için printf("%p",...) kullanmış.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: mcn - 07 Şubat 2012, 19:54:10
Serdar Çiçek in CCS C kitabında da bu şekilde anlatılıyor ama?

char k;   / / char tipinde k isminde degisken tanimlaniyor.
char *x;  / / x adinda gösterici tanimlaniyor.
k = 'a';   / / k degiskeninin içine a karakteri ataniyor.
x = &k;  / / k degiskenin adresi x isaretçisine ataniyor.



Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: fryrmnd - 07 Şubat 2012, 19:56:21
int x;
int *y;
int z;,
z=y;

değil mi hocam?
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 19:57:09
olsa iyi olur. ama derleyici çok kızıyor böyle yapınca :)
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 19:58:59
Alıntı yapılan: mcn - 07 Şubat 2012, 19:54:10
Serdar Çiçek in CCS C kitabında da bu şekilde anlatılıyor ama?

char k;   / / char tipinde k isminde degisken tanimlaniyor.
char *x;  / / x adinda gösterici tanimlaniyor.
k = 'a';   / / k degiskeninin içine a karakteri ataniyor.
x = &k;  / / k degiskenin adresi x isaretçisine ataniyor.

aradığım şey işaretçiye adres atamak değil. işaretçiye atanan adresin ne olduğunu öğrenmek.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: fryrmnd - 07 Şubat 2012, 20:01:25
vallahi  genelde bana  hiç yüz vermiyor bu derleyiciler zaten. yada ben gönüllerini alamıyom  :)
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: JKramer - 07 Şubat 2012, 20:05:35
char z[8];
sprintf(z,"%p",y);

Böyle oluyor ama başka bir yolu vardır herhalde :).
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 20:09:17
"%p" ile adresi string olarak alıp sonra  sayıya çevirmeyi de düşünmedim değil :) 
eğer bilen biri çıkmazsa printf fonksiyonunun deklarasyonuna kadar gideceğim. eğer oradan da çözemezsem,
son çözüm  bu şekilde komik bir çözüm. 
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Tagli - 07 Şubat 2012, 20:12:38
Alıntı yapılan: fryrmnd - 07 Şubat 2012, 19:56:21
int x;
int *y;
int z;,
z=y;

değil mi hocam?

int *z; olarak tanımlanırsa olur sanırım.

Denemedim ama casting ile de olacağını sanıyorum:
int z;
z = (int)y;
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 20:17:07
iki veri tipi de aynı olduğu için casting kullanmayı düşünmemiştim. :)
evet casting ile oluyor.  :)


üzerine biraz düşününce,  neden casting gerektiğini çözdüm.
pointer ve değişken tipleri aynı gibi görünse de aynı değil aslında. birisi int tipinde diğeri ise  adres tipinde bir değişken.
pointerin int pointer olması int tipinde olduğu anlamına gelmiyor.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: JKramer - 07 Şubat 2012, 20:21:32
z = (int)y; şeklinde en başta denemiştim ama bende olmadı, enteresan :).

Ekleme:
   int x,z;
// char z[8];
int *y;

x=0x12345678;
y =  &x;
z=(int)y;

printf("\n Value z=%d",z);

%d yerine %p yazarsak oluyor ama derleyici doğal olarak "warning: format '%p' expects type 'void *', but argument 2 has type 'int'|" uyarısı veriyor.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: elektronikhobi - 07 Şubat 2012, 20:49:18
Alıntı yapılan: Klein - 07 Şubat 2012, 19:23:18
int x;
int *y;

y =  &x

y?

y nin gösterdiği adresi bir değişkene atmayı başaramadım. Gösterilen adresin içeriğini değil. Adresin kendisini. yani y nin içeriğini.

Tam cevap yazmıştım. Baktım soruyu yanlış anlamışım gibi geldi. y'nin gösterdiği adresi başka bir değişkene atmak istiyorsan basitçe başka bir int* türünde gösterge tanımlayıp y'ye atama yaparsın.

int *a = y;

gibi.. Sorunu yanlış anladığımı düşünerek ilk yazdığım cevabı da gönderiyorum.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    char harf = 'H';
    char *p = &harf;
    char **a = &p;

    printf("a'nin adresi: %p\n", a);
    printf("a'nin gosterdigi p'nin adresi: %p\n", *a);

}
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 07 Şubat 2012, 21:25:34
@JKramer  atamaya hata vermiyor  "%d" ile görüntülemeye mi hata veriyor?

@elektronikhobi
iki durumda da yanlış anlaşılma var.
1. cevap  int *a = y; yine işaretçi tanımlamış oluyoruz. bizim istediğimiz adresi  sıradan bir int değişkene almaktı.

2. cevapta da yine adresi  elde edemiyoruz. printf("%p",...) fonksiyonu ile adresi gösteriyoruz. ama biz o adresi alıp bir yerde kullanmak istiyoruz
örneğin   x sayısını a'nın adresi kadar kaydırmak istiyoruz.  ya da  for(i=0,i< a'nın adresi, i++) gibi.


Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: JKramer - 07 Şubat 2012, 23:19:28
%p ile görüntülemeye uyarı veriyor ama adresi doğru gösteriyor. %d ile uyarı vermiyor ama adres hatalı. Zaten adresi z'ye atadıktan sonra artık %d ile görmemiz lazım sanırım.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 08 Şubat 2012, 00:09:07
"%ld" ile dener misin?
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: secretagent - 08 Şubat 2012, 08:24:28



#include <stdio.h>

int main()
{
   int *ptam, tam = 33;

   ptam = &tam;    /* ptam -> tam */

   printf("&tam  = %p\n",&tam);
   printf("ptam  = %p\n",ptam);
   printf("\n");

   printf("tam   = %d\n",tam);
   printf("*ptam = %d\n",*ptam);
   printf("\n");

   *ptam = 44;     /* tam = 44 anlamında */

   printf("tam   = %d\n",tam);
   printf("*ptam = %d\n",*ptam);

return 0;
}


EKRAN ÇIKTISI


&tam  = 0x3fffd14
ptam  = 0x3fffd14

tam   = 33
*ptam = 33

tam   = 44
*ptam = 44


umarım aradığın budur...
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: JKramer - 08 Şubat 2012, 09:17:39
Alıntı yapılan: Klein - 08 Şubat 2012, 00:09:07
"%ld" ile dener misin?
Yok, aynı sonuç. Gcc (Mingw32) ile derliyorum, siz hangi derleyicide denediniz?
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 08 Şubat 2012, 10:55:50
keil

@secretagent  aradığım o değildi. 
Şöyle bir soru sorayım. çözüm ararken ne aradığımızı daha iyi kavrarsın:
int a;
int b;
int *p;
p = &a;
p'nin gösterdiği adres 5 ise  b'nin 5. bitini set et.  p'nin gösterdiği adres 15 ise,  b'nin 15. bitini set et.

Not:
Sorun çözüldü. Kasıt operatörü ile.  Şu an alternatif önerileri konuşuyoruz.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: justice_for_all - 08 Şubat 2012, 11:23:24

int a;
int b;
int *p;
p = &a;


b=b&(1<<p);

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 08 Şubat 2012, 11:32:39
b=b&(1<<p);   error:  #847: expression must have integral or enum type

doğrusu

b= b &(1 << (int)p);
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: justice_for_all - 08 Şubat 2012, 11:34:10
Alıntı yapılan: Klein - 08 Şubat 2012, 11:32:39
b=b&(1<<p);   error:  #847: expression must have integral or enum type

b=b&(1<<(int)p);

bide boyle denermisiniz bu arada hangi derleyicide derliyosunuz?
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 08 Şubat 2012, 11:55:34
Alıntı yapılan: Klein - 08 Şubat 2012, 11:32:39
b=b&(1<<p);   error:  #847: expression must have integral or enum type

doğrusu

b= b &(1 << (int)p);

Sanırım mesajın tamamını okumadan yazdınız. Typecasting ile oluyor. Zaten öyle de olması gerek.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: justice_for_all - 08 Şubat 2012, 12:34:10
simdi bir program denedim ccsde calısıyor sizin derleyicide calısırmı bilemem.

typedef union{
unsigned char structbyte;
struct{
    unsigned  bit_1 : 1;
    unsigned  bit_2 : 1;
    unsigned  bit_3 : 1;
    unsigned  bit_4 : 1;
    unsigned  bit_5 : 1;
    unsigned  bit_6 : 1;
    unsigned  bit_7 : 1;
    unsigned  bit_8 : 1;
  }bits;
} test;



test *p,a1,b1;


p.structbyte= &a1.structbyte;
b1.structbyte=p.structbyte;

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: yamak - 08 Şubat 2012, 13:46:18
Alıntı yapılan: Klein - 08 Şubat 2012, 11:32:39
b=b&(1<<p);   error:  #847: expression must have integral or enum type

doğrusu

b= b &(1 << (int)p);
Hocam aradaki işlemin & değil de | olması gerekmiyo mu? Sizin yazdığınız gibi olursa örneğin b'nin sadece 5. biti 1 ise sadece 5. bit '1' olur geri kalan tüm bitler '0' olur eğer 5.bit '0' ise yine 0 olarak kalmaz mı? Yoksa yanlış mı düşünüyorum?
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 08 Şubat 2012, 14:52:00
@justice_for_all  bu kodla adresi elde etmiş olmadık ki.  a1'in bir baytını b1'in bir baytına attık.

@yamak  oraya takılma. konu başka bir konu olduğu için o önemli değil. bu başlığı ilgilendiren kısım (int)a kısmı. 
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: muhittin_kaplan - 08 Şubat 2012, 18:35:02
Aslında benim aklıma konuyla alakalı başka bir soru geldi.
şimdi Sayi adında bir int değişkenimiz olsun

int Sayi;

Bu değişkenin Adresini Almak İçinde Pointer Tanımlayalım

int *P;

bunların gerçekte uzunlukları Aynımıdır ?

Adres ve Data Uzunlukları Farklı olan İşlemcilerde Durum Dahada iyi anlaşılır (örn 16f piclerde) 
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: z - 08 Şubat 2012, 18:53:12
Bu adres bus genişliği ile alakalı.

Örneğin 16 bit işlemcinizde inteğer değerler 16 bit ile ifade ediliyor fakat bu işlemci 1Mb alanı adresleyebiliyorsa

int pointer 20 bit değer alacak demektir.

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: muhittin_kaplan - 09 Şubat 2012, 00:07:05
Bu Açıdan Neden int tanımladığımız değişkenin adresinide int, short tanımladığımızı short yapıyoruz ?
Bu tanımladığımız Pointer RAM bölgede yer kaplıyor değil mi ? ozaman 16bit gereken bir yerde biz 32bit yer ayırmış olmuyormuyuz ? yada long tanımlı bir pointerde tam tersi olmuyor mu ? (32 bit gerekirken değişkenimiz 64 diye pointeri de 64 tanımlamak durumundayız )
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: justice_for_all - 09 Şubat 2012, 00:53:06
Alıntı yapılan: Klein - 08 Şubat 2012, 14:52:00
@justice_for_all  bu kodla adresi elde etmiş olmadık ki.  a1'in bir baytını b1'in bir baytına attık.

p.structbyte= &a1.structbyte; bu adres atamak değilmi ben mi yalnıs biliyorum ? hadi ben yalnıs biliyorum diyelim mplab sim dem yalnıs simule ediyor?

mplabda simule ettigimde a1in adresi 0x1c olarak gordum sonra bu adresi p pointerine attım sonrada pointer degerini b değişkenine atadım donusum yapmadan.ve b1 in byte degişkeninde 0x1c degerini ve buna baglı olarakda 0x1c nin bitlerine ayrılmıs seklini gordum

sonuc olarak

b= (int)p);
bu veya
b= p);

derkeyiciye gore değistigine kanaat getirdim.(sizin derleyicinizde olmadığını varsayarak..)
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: z - 09 Şubat 2012, 01:51:10
Alıntı yapılan: muhittin_kaplan - 09 Şubat 2012, 00:07:05
Bu Açıdan Neden int tanımladığımız değişkenin adresinide int, short tanımladığımızı short yapıyoruz ?
Bu tanımladığımız Pointer RAM bölgede yer kaplıyor değil mi ? ozaman 16bit gereken bir yerde biz 32bit yer ayırmış olmuyormuyuz ? yada long tanımlı bir pointerde tam tersi olmuyor mu ? (32 bit gerekirken değişkenimiz 64 diye pointeri de 64 tanımlamak durumundayız )

Degiskenin ne olursa olsun buna erisecek pointer hep adres saklar. Ornegin 32bit islemcinin adres busi da 32 bit ise bu durumda pointerlerin tamami 32 bit demektir.
Sen istersen 64 hatta 128 bit veri sakla buna erisecek pointer gene 32 bit olacaktir.

Alıntı Yap
Bu Açıdan Neden int tanımladığımız değişkenin adresinide int, short tanımladığımızı short yapıyoruz ?


Burda nuans farki var.

Short tanimli degiskenlere erisecek pointeri short tanimlamiyoruz. Diyoruz ki, sen short degiskenlere ulasacak bir pointersin. Burada adi gecen short, daha acik ifadeyle short*, short degiskenlerin pointeri demek.

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: Klein - 09 Şubat 2012, 12:03:23
@muittin
şöyle düşün:

Eğer pointerimizin kapladığı alan değişkenimizle aynı olsydı ne olurdu?

char b; // adresi 0xFFFF;
char *p;

p = &b;
bu işlemde b nin adresi p ye atılıyor.  eğer p'nin kapladığı alan char( 8 bit olsaydı) bu 16 bitlik adresi nasıl tutacaktı?

peki pointer hep adreslenecek alanın büyüklüğü kadar örn 32 bit ise. neden char, int ya da short diye tanımlıyoruz? ptr deyip geçelim.

char a[100];
int b[100];
ptr *p;

p = a; dedik. a'nın adresini p ye attık.  veya p = b dedik. buraya kadar sorun yok.  peki p++; dediğimizde ne olacak? p nin değeri ne kadar artırılacak?  int pointer ise 2 byta , char pointer ise 1 byte.  işte bu int , char , short gibi tanımlamalar da burada devreye giriyor.

bir de void pointerler var. bunlarda tip tanımı yok.
char a;
int b;
long c;

void *p;

p = &a;
p=&b;
p=&c;

gibi kullanılabilir. derleyici pointerin tipini eşleştiği veri tipine göre kendisi seçer. Ama bu tip bir kullanım hata yapmaya çok müsait olduğu için pek önerilmez. 

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: muhittin_kaplan - 09 Şubat 2012, 14:37:40
Alıntı Yapp = a; dedik. a'nın adresini p ye attık.  veya p = b dedik. buraya kadar sorun yok.  peki p++; dediğimizde ne olacak? p nin değeri ne kadar artırılacak?  int pointer ise 2 byta , char pointer ise 1 byte.  işte bu int , char , short gibi tanımlamalar da burada devreye giriyor.
evet bu güzel oldu.
Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: z - 09 Şubat 2012, 15:52:30
Alıntı Yap
p = a; dedik. a'nın adresini p ye attık.  veya p = b dedik. buraya kadar sorun yok.  peki p++; dediğimizde ne olacak? p nin değeri ne kadar artırılacak?  int pointer ise 2 byta , char pointer ise 1 byte.  işte bu int , char , short gibi tanımlamalar da burada devreye giriyor.

Nedenlerden birisi bu fakat daha önemlisi şu;

Diyelimki ardışıl adreslerde 0x00, 0x01, 0x02, 0x03 verileri var ve pointer 0x00 değeri saklayan adresi gösteriyor.

Pointerin gösterdiği yerdeki veri

0x00, 0x1000, 0x03021000 den herhangi birisi olabilir.

Veri olarak bunlardan hangisinin okunacağı, pointerin tipi ile alakalı.

Başlık: Ynt: İşaretçinin gösterdiği adresi elde etmek
Gönderen: mufitsozen - 09 Şubat 2012, 16:12:33
Alıntı yapılan: bunalmis - 09 Şubat 2012, 15:52:30

Nedenlerden birisi bu fakat daha önemlisi şu;

Diyelimki ardışıl adreslerde 0x00, 0x01, 0x02, 0x03 verileri var ve pointer 0x00 değeri saklayan adresi gösteriyor.

Pointerin gösterdiği yerdeki veri

0x00, 0x1000, 0x03021000 den herhangi birisi olabilir.

Veri olarak bunlardan hangisinin okunacağı, pointerin tipi ile alakalı.
kucuk bir ek bilgi, bunun bir little-endian bir mimari icin olmasi (ornegin x86 icin), ARM mimarisinde ise little yada big endian olup olmadigi kontrol registerlarindan okunmasi lazim