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ış.
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.
int x;
int *y;
int z;,
z=y;
değil mi hocam?
olsa iyi olur. ama derleyici çok kızıyor böyle yapınca :)
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.
vallahi genelde bana hiç yüz vermiyor bu derleyiciler zaten. yada ben gönüllerini alamıyom :)
char z[8];
sprintf(z,"%p",y);
Böyle oluyor ama başka bir yolu vardır herhalde :).
"%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.
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;
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.
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.
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);
}
@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.
%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.
"%ld" ile dener misin?
#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...
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?
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.
int a;
int b;
int *p;
p = &a;
b=b&(1<<p);
b=b&(1<<p); error: #847: expression must have integral or enum type
doğrusu
b= b &(1 << (int)p);
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?
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.
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;
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?
@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ı.
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)
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.
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 )
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..)
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.
@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.
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.
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ı.
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