C/C++ RAM'lerde adres mantığı ve C++ pointerlar

boobie

Picopat
Katılım
8 Temmuz 2023
Mesajlar
136
Yer
Ankara
Daha fazla  
Cinsiyet
Erkek
İnt main() {

İnt a = 5; // a değişkeninin adres değeri 1000 olsun.(1000-1001-1002-1003 işgal eder.)

İnt *ptr = &a;

Cout << "değişkenin adresi: " << &a << endl; // a değişkeni bu adreste saklanıyor.
Cout << "değişkenin adresi: " << ptr << endl; // a değişkeni bu adreste saklanıyor.

Cout << "değişkenin değeri: " << *ptr << endl; // adrese git ve kutunun içindeki değeri söyle.

*Ptr = 7; // adrese git ve kutunun içindeki değeri 7 olarak değiştir.

Cout << "değişkenin yeni değeri: " << a << endl;

Return 0;
}

Merhaba arkadaşlar bir üniversitede bilgisayar mühendisliği öğrencisiyim. 1.sınıfta fonksiyonlara kadar C öğrendik, çok üstüne gitmedim fakat temelim var. Gelecek dönem C++'de pointerlar ve sonrasında C++ öğreneceğiz diye kendi başıma C++ öğreniyorum. Yazılım bilimi YouTube kanalından devam ediyorum. Oradaki eğitmen pointerların ilk giriş dersinde böyle anlattı. Ben de tam oturmadığı için buraya sormak istiyorum. Şöyle oturmadı ki oradaki eğitmen bir a değişkeni tanımlayıp ona bir pointer atayarak adresini gösteriyor. Output şöyle çıkıyor: 0xc738bffa34. benim anlamadığım buradaki değer nedir, adres nedir? RAM'lerdeki adresler nasıl oluşturulur? Buradaki sayı böyle karmaşıkken hoca 1000 örneğini veriyor. RAM'da o yer ayrıldı diyelim. Hoca burada kutucuk örneğini veriyor. A değişkeni tanımlıyor ve örnek olarak 1000 adresinde saklı olsun diyor. İnteger 4 byte kapladığı için 1000-1001-1002-1003 değerinde tutulur diyor. Ama bir byte zaten 8 bit. Ek olarak bunların her biri bir kutucuk ise her kutucukta 5 mi yazıyor? Bilmiyorum görselleştiremedim açıkçası bu pointerları tam olarak kavramak için bir görsel kaynağa ihtiyacım var sanırım. Belki bilgisayarların ve RAM'lerin çalışma mantığını tam olarak bilmediğimden oluyordur. Hani her şey 0 ve 1 ile çalışıyor devrelerle çalışıyor biliyorum fakat oradaki adres neyi temsil ediyor ve 5 değerini nasıl tutuluyor net olarak açıklayabilen biri olursa çok mutlu olurum. Video PDF bununla ilgili her kaynağa da açığım arkadaşlar teşekkür ederim.
 
Bu konular; adresleme vb. yani ileriki sınıflardaki derslerde, özellikle işletim sistemleri dersinde pekişecek.

Ben sadece şöyle basit bir örnek vereyim, madem görsel istiyorsun.

Screenshot 2024-02-11 at 18-44-50 0 k5br6SBvvsNBSH48.webp (WEBP Image 875 × 477 pixels).png


Adres değerlerini teorik olarak düşünmen lazım, yani hocan gidip de 0x7ffe6cdf7974 gibi adres vererek anlatacağına böyle sayılar ile anlatıyor anlaşılması için. Integer'ın değeri, signed (pozitif negatif olma durumu ilk bitte tutulur)/unsigned(ilk bit de dahil olarak düşün, 32 bit) olması durumuna göre bu 4 bytelık alanda saklanır. Yani integer 5 ise sadece ilk bytedaki 00000101 değeri yeterli, diğer bytelar 0 olacaktır.
 
Bu konular; adresleme vb. yani ileriki sınıflardaki derslerde, özellikle işletim sistemleri dersinde pekişecek.

Ben sadece şöyle basit bir örnek vereyim, madem görsel istiyorsun.

Eki Görüntüle 2113655

Adres değerlerini teorik olarak düşünmen lazım, yani hocan gidip de 0x7ffe6cdf7974 gibi adres vererek anlatacağına böyle sayılar ile anlatıyor anlaşılması için. Integer'ın değeri, signed (pozitif negatif olma durumu ilk bitte tutulur)/unsigned(ilk bit de dahil olarak düşün, 32 Bit) olması durumuna göre bu 4 bytelık alanda saklanır. Yani integer 5 ise sadece ilk bytedaki 00011001(25) değeri yeterli, diğer bytelar 0 olacaktır.

Daha sonra görecek olmama sevindim, teşekkür ederim hocam. Paylaştığınız görsel gayet açıklayıcı olmuş ama eğer 5 değerini tutuyorsak ve 00000101 şeklinde olacaksa o zaman 1byte yer kaplamaz mı? Bu durumda diğer byteler boş mu kalacak o zaman sayısının değerine göre depoladığı byte değeri değişiyor mu?
 
Daha sonra görecek olmama sevindim, teşekkür ederim hocam. Paylaştığınız görsel gayet açıklayıcı olmuş ama eğer 5 değerini tutuyorsak ve 00000101 şeklinde olacaksa o zaman 1byte yer kaplamaz mı? Bu durumda diğer byteler boş mu kalacak o zaman sayısının değerine göre depoladığı byte değeri değişiyor mu?

Değişkeni tanımlarken siz ne seçerseniz, yani örneğin integer seçerseniz 4 byte, short int seçerseniz 2 byte vb. o kadar byte kullanılır. Bu sayıların alabileceği max/min değerler vardır. Kodlama yaparken değişkenleri doğru kullanmak çok önemlidir.

En basit mantıkla, diyelim ki siz çok da büyük olmayan, olacağı düşünülmeyen numerik bir veriyi tutacaksınız.
Integer, long vb. kullanmak saçma olur, gereksiz yere Memory yemiş olursunuz.

Eskiden, sistem kaynaklarının yetersiz olduğu tarihlerde, mesela 8 bitlik oyun konsolları zamanında oyun geliştirirken efficiency çok daha önemliymiş. Yıllar geçtikçe, sistem kaynakları bollaştıkça bu durum gittikçe önemsizleşiyor, yine de iyi mühendis buna dikkat eder, özellikle de C, C++ gibi daha low dilleri kullanıyorsa.

Neyse, eğer değişkeninizi integer tanımlarsanız diğer bytelar 000.. olarak duracak. Ancak canınız isterse değişkeninize int Max değerine kadar değer atayabilmenizi sağlayacak. Siz int dediğinizde o Memory'deki 4 byte sizin integerınız için allocate edildi.
Siz derseniz ki ben değişkenimde dünyanın toplam nüfusunu tutacağım, int yetmez, long seçmeniz gerekir.
Ha derseniz ki benim tutacağım değer öyle milyonlarla milyarlarla alakalı bir şey değil, küçük bir şey, short int vb. kullanırsınız.
Virgüllü sayılarda da basit bir şeyse float, küsuratın basamakları çok ve önemliyse double kullanırsınız vb. Hangi değişkeni seçerseniz ona karşılık miktarda byte Memory'de allocate edilir.
 
Değişkeni tanımlarken siz ne seçerseniz, yani örneğin integer seçerseniz 4 byte, short int seçerseniz 2 byte vb. o kadar byte kullanılır. Bu sayıların alabileceği max/min değerler vardır. Kodlama yaparken değişkenleri doğru kullanmak çok önemlidir.

En basit mantıkla, diyelim ki siz çok da büyük olmayan, olacağı düşünülmeyen numerik bir veriyi tutacaksınız.
Integer, long vb. kullanmak saçma olur, gereksiz yere Memory yemiş olursunuz.

Eskiden, sistem kaynaklarının yetersiz olduğu tarihlerde, mesela 8 bitlik oyun konsolları zamanında oyun geliştirirken efficiency çok daha önemliymiş. Yıllar geçtikçe, sistem kaynakları bollaştıkça bu durum gittikçe önemsizleşiyor, yine de iyi mühendis buna dikkat eder, özellikle de C, C++ gibi daha Low dilleri kullanıyorsa.

Neyse, eğer değişkeninizi integer tanımlarsanız diğer bytelar 000.. Olarak duracak. Ancak canınız isterse değişkeninize int Max değerine kadar değer atayabilmenizi sağlayacak. Siz int dediğinizde o Memory'deki 4 byte sizin integerınız için allocate edildi.
Siz derseniz ki ben değişkenimde dünyanın toplam nüfusunu tutacağım, int yetmez, long seçmeniz gerekir.
Ha derseniz ki benim tutacağım değer öyle milyonlarla milyarlarla alakalı bir şey değil, küçük bir şey, short int vb. kullanırsınız.
Virgüllü sayılarda da basit bir şeyse float, küsuratın basamakları çok ve önemliyse double kullanırsınız vb. hangi değişkeni seçerseniz ona karşılık miktarda byte Memory'de allocate edilir.

Şimdi daha iyi oturdu teşekkürler. Şunu da sormak istiyorum. Pointer değişkenleri biraz daha araştırdığımda aslında bellekte başka bir değişkenin adresini tutan tam sayı değer olduğunu anladım. Madem böyle ben mesela int = a değeri için bir adres değişkeni tanımlıyorum (pa) ve adresimiz 1000 olsun. Ben bu pointer üzerinde aritmetik bir işlem yapayım dedim ve 1 ekledim(ptr+1). Sonuç 1004 oldu. Normalde eğer bu bir değişken ise 1001 olması gerekirdi. Acaba bilgisayar bunun bir adres değişkeni tuttuğunu, integer bir adres değişkeni olduğunu bildiğinden eğer ileride yine bu pointer ile bir integer bulmak istersek 4 arttırarak gitmemiz lazım deyip o yüzden mi bunu yapıyor? Peki böyleyse ya o değer normal sayı olsaydı, bunu bilgisayar ve derleyici nasıl oluyor da anlıyor merak etmiyor değilim açıkçası. Bir de dediğiniz her 1 ve 0 değeri için transistörler ve elektrik devreleri kullanıldığını bellek aracılığıyla işlemciye yönlendirilip işlemcinin o 32 Bit'lik çizgi boyunca bunu okuyup 5 değerini okuduğunu düşünüyorum doğru mudur? Son olarak bu bellek değerleri olabildiğince çok olabilsin diye mi hexadecimal kullanıyoruz hocam? Kusura bakmayın fazla sordum ama ben biraz mantığını fazla kurcalayan biriyim sanırım...😅

C++:
int main() {

 int a = 5;
 int *ptr = &a;

 cout << "Değişkenin Adresi: " << ptr << endl; //Değişkenin adres değerini tutan integer.
 cout << "Değişkenin Adresi: " << ptr+1 << endl; //Adres değerine +1 eklenmesi.

 /* OUTPUT.
 Değişkenin Adresi: 0xd38d5ff6c4.
 Değişkenin Adresi: 0xd38d5ff6c8.
 */

@Vavien. Hocam müsaitseniz siz de bakar mısınız?
 
Son düzenleme:
Şimdi daha iyi oturdu teşekkürler. Şunu da sormak istiyorum. Pointer değişkenleri biraz daha araştırdığımda aslında bellekte başka bir değişkenin adresini tutan tam sayı değer olduğunu anladım. Madem böyle ben mesela int = a değeri için bir adres değişkeni tanımlıyorum (pa) ve adresimiz 1000 olsun. Ben bu pointer üzerinde aritmetik bir işlem yapayım dedim ve 1 ekledim(ptr+1). Sonuç 1004 oldu. Normalde eğer bu bir değişken ise 1001 olması gerekirdi. Acaba bilgisayar bunun bir adres değişkeni tuttuğunu, integer bir adres değişkeni olduğunu bildiğinden eğer ileride yine bu pointer ile bir integer bulmak istersek 4 arttırarak gitmemiz lazım deyip o yüzden mi bunu yapıyor? Peki böyleyse ya o değer normal sayı olsaydı, bunu bilgisayar ve derleyici nasıl oluyor da anlıyor merak etmiyor değilim açıkçası. Bir de dediğiniz her 1 ve 0 değeri için transistörler ve elektrik devreleri kullanıldığını bellek aracılığıyla işlemciye yönlendirilip işlemcinin o 32 Bit'lik çizgi boyunca bunu okuyup 5 değerini okuduğunu düşünüyorum doğru mudur? Son olarak bu bellek değerleri olabildiğince çok olabilsin diye mi hexadecimal kullanıyoruz hocam? Kusura bakmayın fazla sordum ama ben biraz mantığını fazla kurcalayan biriyim sanırım...😅

C++:
int main() {

 int a = 5;
 int *ptr = &a;

 cout << "Değişkenin Adresi: " << ptr << endl; //Değişkenin adres değerini tutan integer.
 cout << "Değişkenin Adresi: " << ptr+1 << endl; //Adres değerine +1 eklenmesi.

 /* OUTPUT.
 Değişkenin Adresi: 0xd38d5ff6c4.
 Değişkenin Adresi: 0xd38d5ff6c8.
 */
Evet, c++ orada int olduğunu bildiği için yani 4 byte tutulduğunu bildiği için 4 arttırıyor, double yapsan mesela 8 arttıracaktı, değişken adresini farklı data tipleri için deneyebilirsin, 0xd38d5ff6c8 4 artmış mesela, double yapsan 8 artacaktı (direkt bir sonraki ilk boş yerden devam ettiği (first fit) durumda, best fit, worst fit vb. olaylar var işletim sisteminde memory managementta ama ben de unutmuşum iyice, sen araştırırsan daha iyi olur).
Hexadecimal notationla ilgili sorduğun soruyu tam anlamadım.

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
şu ikisine göz atmanı tavsiye ederim.
 
Etiketlendigim için yazıyorum. Düzgün kod bile paylasamiyorsunuz. Koca metni tek paragraf yapmışsınız gibi duruyor. Hiç okuma hevesi uyandırmadı.

Arada gözüme çarpan için şunu söyleyebilirim. 4 artmasını sebebi veri tipinin int* olması. Orada değişkeni adresine 1 eklemiyorsunuz. Değişkeni adresini barındıran bir pointer'a 1 ekliyorsunuz. O bir int* ne değeri verirseniz onu tutar.

Ezber şekilde giderseniz farklı kullanım gördüğünüzde afallarsiniz.
 
Evet, C++ orada int olduğunu bildiği için yani 4 byte tutulduğunu bildiği için 4 arttırıyor, double yapsan mesela 8 arttıracaktı, değişken adresini farklı data tipleri için deneyebilirsin, 0xd38d5ff6c8 4 artmış mesela, double yapsan 8 artacaktı (direkt bir sonraki ilk boş yerden devam ettiği (first fit) durumda, best fit, worst fit vb. olaylar var işletim sisteminde MEMORY_MANAGEMENT'ta ama ben de unutmuşum iyice, sen araştırırsan daha iyi olur).
Hexadecimal notationla ilgili sorduğun soruyu tam anlamadım.

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
şu ikisine göz atmanı tavsiye ederim.

Direkt bellek adreslerinde neden hexadecimal kullanılıyor diye sormuştum hocam. Teşekkür ederim videolar için. Bir de şu koda bakar mısınız kendim merak edip deniyorum da dediğiniz gibi integer olunca 4 double olunca 8 artıyor. Şu an arraylerle pointerların ilişkisine bakıyorum da mesela bir int array tanımlarsam ve bu array için bir int pointer tanımlarsam ve sonra 1 arttırırsam 4 artıyor hiçbir problem yok. Ama, bir string array tanımlarsam ve aynı işlemi yaparsam adres değerini 20 arttırıyor. Bunun mantığını anlamadım çünkü yazdığım elemanların byte değerini hesapladığımda 32 çıkıyor. Nasıl mümkün olabilir iç içe mi geçiyorlar?
C++:
int main() {

 int array[] = {1,2,3,4};

 int* pArray = array;

 cout << "Pointer değeri: " << pArray << endl;
 pArray++;
 cout << "Pointer yeni değeri: " << pArray << endl;

 string arrayNew[] = {"X" , "Y" , "Z"};
 string* pStr = arrayNew;

 cout << pStr << endl;
 cout << pStr +1 << endl;

 string a = "X"; //+20 olduğundan x kaç byte tuttuğunu merak ettim.
 cout << sizeof(X) << endl; //Sonuç 32.

 /* OUTPUT.
 Pointer değeri: 0x28c21ff7f8.
 Pointer yeni değeri: 0x28c21ff7fc.
 0xb403ffb10.
 0xb403ffb30.
 32 --> byte.

 return 0;

Etiketlendigim için yazıyorum. Düzgün kod bile paylasamiyorsunuz. Koca metni tek paragraf yapmışsınız gibi duruyor. Hiç okuma hevesi uyandırmadı.

Arada gözüme çarpan için şunu söyleyebilirim. 4 artmasını sebebi veri tipinin int* olması. Orada değişkeni adresine 1 eklemiyorsunuz. Değişkeni adresini barındıran bir Pointer'a 1 ekliyorsunuz. O bir int* ne değeri verirseniz onu tutar.

Ezber şekilde giderseniz farklı kullanım gördüğünüzde afallarsiniz.

Anlatılan aslında bir p değişkeni tanımlanıp içine adres değeri yazıldığı. Dolayısıyla bir sayı olduğundan neden +1 olmayacağını düşündüm. Sonrasında C++'ın bunu bir pointer olarak algılayıp tekrar integer bulabilmesi adına 4 arttığı çıkarımını yaptım. Pointer deyince çok havada kalıyor çünkü sadece bir değişken tanımlamışsın gibi oluyor. Mantığı ise C++'nın pointer olarak görmesinde yatıyor sanırım.

Haklısınız ezberlersek çuvallarız o yüzden de mantığını oturtmaya çalışıyorum. Kodu ilk yazdığımda nasıl paylaşacağımı bilmiyordum, öğrendim. Paragrafı uzun yazmışım haklısınız.
 
Son düzenleme:
Direkt bellek adreslerinde neden hexadecimal kullanılıyor diye sormuştum hocam. Teşekkür ederim videolar için. Bir de şu koda bakar mısınız kendim merak edip deniyorum da dediğiniz gibi integer olunca 4 double olunca 8 artıyor. Şu an arraylerle pointerların ilişkisine bakıyorum da mesela bir int array tanımlarsam ve bu array için bir int pointer tanımlarsam ve sonra 1 arttırırsam 4 artıyor hiçbir problem yok. Ama, bir string array tanımlarsam ve aynı işlemi yaparsam adres değerini 20 arttırıyor. Bunun mantığını anlamadım çünkü yazdığım elemanların byte değerini hesapladığımda 32 çıkıyor. Nasıl mümkün olabilir iç içe mi geçiyorlar?
C++:
int main() {

 int array[] = {1,2,3,4};

 int* pArray = &array;

 cout << "Pointer değeri: " << pArray << endl;
 pArray++;
 cout << "Pointer yeni değeri: " << pArray << endl;

 string arrayNew[] = {"X" , "Y" , "Z"};
 string* pStr = arrayNew;

 cout << pStr << endl;
 cout << pStr +1 << endl;

 string a = "X"; //+20 olduğundan x kaç byte tuttuğunu merak ettim.
 cout << sizeof(X) << endl; //Sonuç 32.

 /* OUTPUT
 Pointer değeri: 0x28c21ff7f8
 Pointer yeni değeri: 0x28c21ff7fc
 0xb403ffb10
 0xb403ffb30
 32 --> byte

 return 0;



Anlatılan aslında bir p değişkeni tanımlanıp içine adres değeri yazıldığı. Dolayısıyla bir sayı olduğundan neden +1 olmayacağını düşündüm. Sonrasında C++'ın bunu bir pointer olarak algılayıp tekrar integer bulabilmesi adına 4 arttığı çıkarımını yaptım. Pointer deyince çok havada kalıyor çünkü sadece bir değişken tanımlamışsın gibi oluyor. Mantığı ise C++'nın pointer olarak görmesinde yatıyor sanırım.

Haklısınız ezberlersek çuvallarız o yüzden de mantığını oturtmaya çalışıyorum. Kodum return unutmam dışında doğru, daha dikkat ederim. Paragrafı uzun yazmışım haklısınız.
Hexadecimal gösterimin nasıl bir olayı var diye internette bakındım, iş görmesi ve human readable olması sebebiyle deniyor, benim de bir bilgim yok malesef.

Stringler için heap memory kullanılır, int gibi sabit bir allocation yapılmıyor yani, heap memorydeki konum bilgisi tutuluyor (c++ konusunda bilgili arkadaşlar daha iyi yardımcı olacaktır), şöyle bir video buldum bunun için de

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
 
Algılama falan yok. O bir pointer. Veri tipi integer pointer'ı ya da her ne pointer'ı ise o. +, ++ vb. pointer aritmetiği yapılan operatörler adlarından da anlaşılabileceği gibi operatörler. O şekilde tasarlandıkları için o şekilde davranıyorlar.

Pointer kullanılan her örneği gözden geçirerek öğrenemezsiniz. Zamanla oturur. Bu kadar deşmenize gerek yok.

Class olduğu için member variable'larına bakıyor sizeof operatörü.

std::string nesneleri;
  • char* data
  • std::size_t size
  • std::size_t capacity
  • bir de herhalde referans sayısını tutuyor (herhalde ki yüzden 32 çıktı).
Tipler birebir aynı olmayabilir. IDE kullanıyorsanız kütüphane içinde arayabilirsiniz. Şu anda bende kurulu değil. Boyut derleyiciye göre değişiklik gösterebilir.
Kod:
#include <iostream>
#include <string>

int main() {
    std::cout << sizeof std::string{ "X" } << '\n';     // 32
    std::cout << sizeof std::string{ "XY" } << '\n';    // 32
    return 0;
}

Buna ek olarak alignment var ama standart kütüphanede onlar güzelce ayarlanmış durumda.

Şunu da okuyucuya ödev olarak bırakayım.
Kod:
#include <iostream>

typedef struct A {
    char a;
    char b;
    char c;
    char d;
    int e;
} A;

typedef struct B {
    char a;
    char b;
    char c;
    int e;
    char d;
} B;

int main() {
    std::cout << sizeof A() << '\n';
    std::cout << sizeof B() << '\n';
    return 0;
}


Bunlar bulunduğunuz aşamada işinize yaramayacak şeyler. Bu tarz soruları soracak duruma geldiğinizde zaten İngilizce şekilde Google amcaya sorabilecek hale de gelmiş olmanız gerekiyor. Daha geniş kaynak sizi bekliyor.

Diğer arkadaş niye heap ile kafayı bozmuş anlamadım.
 

Yeni konular

Geri
Yukarı