CPP 028 – Pointers

Ne hikmetse çok zor olduğu düşünülen aslında zor olmayan sadece arada bir karıştılmaya müsait adres tutan değişkenlere pointer diyoruz. Point etmek aşağı yukarı işaret etmek anlamına geliyor. Bildiğin işaret parmağıyla işaret etmek olara düşünebilirsiniz.

  • Değişkenlerimiz bellekte belli bir adreste tutulur.
  • Pointer’da bir değişken olarak bellekte belli bir adrese sahiptir. Herhangi bir değişkenin adresini görebilmek için addres of & operatörünü kullanıyoruz.
  • Diğer değişkenler tamsayı, noktalı sayı, karakter gibi şeyleri tutarken, pointer değişkeni adres tutuyor. Yani temelde adres de bir sayı olduğuna göre integer gibi bir sayı tutuyor.
  • Pointer’ın tuttuğu adresi görebilmek için değişkenin ismini kullanıyoruz: örneğin cout << ptr … şeklinde ekrana basabiliriz.
  • Pointer’ın işaret ettiği değişkenin değerini alabilmek için de *ptr kullanıyoruz.
  • pointerı tanımlamak için
    • int *ptr;
    • char *ptr;
    • bool *ptr;
    • şeklinde değişken isminin sol tarafına * koyarak tanımlıyoruz.
#include <iostream>
#include <vector>
using namespace std;

int main() {
	int i = 5;

	int *ptr;
	ptr = &i;

	cout << "address of i: " << &i << endl;
	cout << "ptr: " << ptr << endl;
	cout << "address of ptr: " << &ptr << endl;
	cout << "*ptr: " << *ptr << endl;

	// address of i :   000000FE1A7DFBA4
	// ptr :            000000FE1A7DFBA4
	// address of ptr : 000000FE1A7DFBC8
	// *ptr : 5

}
  • Referanslar gibi pointerları fonksiyonlara atabiliriz:
#include <iostream>
using namespace std;

void func(int* ptr) {
	(*ptr)++; // operator önceliğine dikkat etmek gerekli. 
}

int main() {
	int i = 5;
	func(&i);
	cout << i << endl;
}

Arrayleri de işin içine katabiliriz

#include <iostream>
#include <vector>
using namespace std;

void sum(int* a, int* b, int count) {
	for (int i{}; i < count; i++) {
		a[i] = a[i] + b[i];
	}
}
void print_arr(int* arr, int count) {
	for (int i{}; i < count; i++)
		cout << arr[i] << ", ";
	cout << endl;
}

int main() {
	int a[]{ 3, 4,5,6,1 };
	int b[]{ 34,1,2,53,2 };

	print_arr(a, 5); // 3,  4, 5,  6, 1,
	print_arr(b, 5); // 34, 1, 2, 53, 2,
		
	sum(a, b, 5);
	print_arr(a, 5); // 37, 5, 7, 59, 3,

}

burada fonksiyona array’in adresini atıyoruz. Array’i [] olmadan yazdırırsak direk bize başlangıç adresini yani ilk elemanının adresini verir.

int main() {
	int a[]{ 3, 4,5,6,1 };
	int b[]{ 34,1,2,53,2 };

	cout << a << endl;     // 00000095A5CFF838
	cout << &a[0] << endl; // 00000095A5CFF838

Yani kısacası pointerları avantajlı yapan noktalardan biri büyük yapıları bellekte kopyalamadan fonksiyonlara atabilmek.

Peki array yerine referans ile atamaz mıydık? Atabilirdik:

void print_arr(int (&arr)[], int count) {
	for (int i{}; i < count; i++)
		cout << arr[i] << ", ";
	cout << endl;
}

Tabi aslında günlük kullanımda bunu yapmaya mecbur değilsek (çalıştığımız kod böyle yazıldıysa bunu modifiye ederken de mecburen bunları kullanıyoruz)

Mecbur değilsek std::vector gibi daha insancıl yapıları kullanıyoruz:

// burada iki vektorü kopyalıyoruz
vector<int> sum_by_copy(vector<int> a, vector<int> b) {
	for (int i{}; i < a.size(); i++) 
		a[i] = a[i] + b[i];
	return a;
}

// bunda ise kopyalama işlemi olmuyor
void sum_by_reference(vector<int>& a, vector<int>& b) {
	for (int i{}; i < a.size(); i++)
		a[i] = a[i] + b[i];
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *