logo

C'de İşaretçi Aritmetiği

İşaretçiler üzerinde toplama, çıkarma vb. aritmetik işlemler yapabiliriz. Ancak işaretçinin adresi içerdiğini bildiğimiz için, diğer işlenen tamsayı tipindeyse işaretçi üzerinde yapılan aritmetik işlemin sonucu da bir işaretçi olacaktır. İşaretçiden işaretçiden çıkarma işleminde sonuç bir tamsayı değeri olacaktır. C dilinde işaretçi üzerinde aşağıdaki aritmetik işlemler mümkündür:

  • Artış
  • Azaltma
  • Ek
  • Çıkarma
  • Karşılaştırmak

C'de İşaretçiyi Artırma

Eğer işaretçiyi 1 arttırırsak işaretçi hemen bir sonraki konumu göstermeye başlayacaktır. Bu, genel aritmetikten biraz farklıdır çünkü işaretçinin değeri, işaretçinin işaret ettiği veri türünün boyutuna göre artacaktır.

Dizinin her elemanını işaret etmeye devam edecek, üzerinde bazı işlemler gerçekleştirecek ve kendisini bir döngü içinde güncelleyecek bir işaretçi üzerindeki artış işlemini kullanarak bir diziyi dolaşabiliriz.

İşaretçiyi artırma kuralı aşağıda verilmiştir:

 new_address= current_address + i * size_of(data type) 

i işaretçinin artırılacağı sayıdır.

32 bit

32 bitlik int değişkeni için 2 bayt artırılacaktır.

64 bit

64 bitlik int değişkeni için 4 bayt artırılacaktır.

64 bit mimaride işaretçi değişkenini artırma örneğini görelim.

ekran boyutu nasıl öğrenilir
 #include int main(){ int number=50; int *p;//pointer to int p=&number;//stores the address of number variable printf('Address of p variable is %u 
',p); p=p+1; printf('After increment: Address of p variable is %u 
',p); // in our case, p will get incremented by 4 bytes. return 0; } 

Çıktı

 Address of p variable is 3214864300 After increment: Address of p variable is 3214864304 

İşaretçiyi kullanarak bir diziyi geçme

 #include void main () { int arr[5] = {1, 2, 3, 4, 5}; int *p = arr; int i; printf('printing array elements...
&apos;); for(i = 0; i<5; i++) { printf('%d ',*(p+i)); } < pre> <p> <strong>Output</strong> </p> <pre> printing array elements... 1 2 3 4 5 </pre> <h2>Decrementing Pointer in C</h2> <p>Like increment, we can decrement a pointer variable. If we decrement a pointer, it will start pointing to the previous location. The formula of decrementing the pointer is given below:</p> <pre> new_address= current_address - i * size_of(data type) </pre> <h3>32-bit</h3> <p>For 32-bit int variable, it will be decremented by 2 bytes.</p> <h3>64-bit</h3> <p>For 64-bit int variable, it will be decremented by 4 bytes.</p> <p>Let&apos;s see the example of decrementing pointer variable on 64-bit OS.</p> <pre> #include void main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p-1; printf(&apos;After decrement: Address of p variable is %u 
&apos;,p); // P will now point to the immidiate previous location. } </pre> <p> <strong>Output</strong> </p> <pre> Address of p variable is 3214864300 After decrement: Address of p variable is 3214864296 </pre> <h2>C Pointer Addition</h2> <p>We can add a value to the pointer variable. The formula of adding value to pointer is given below:</p> <pre> new_address= current_address + (number * size_of(data type)) </pre> <h3>32-bit</h3> <p>For 32-bit int variable, it will add 2 * number.</p> <h3>64-bit</h3> <p>For 64-bit int variable, it will add 4 * number.</p> <p>Let&apos;s see the example of adding value to pointer variable on 64-bit architecture.</p> <pre> #include int main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p+3; //adding 3 to pointer variable printf(&apos;After adding 3: Address of p variable is %u 
&apos;,p); return 0; } </pre> <p> <strong>Output</strong> </p> <pre> Address of p variable is 3214864300 After adding 3: Address of p variable is 3214864312 </pre> <p>As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is 3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it increments 12. But if we were using 32-bit architecture, it was incrementing to 6 only, i.e., 2*3=6. As integer value occupies 2-byte memory in 32-bit OS.</p> <h2>C Pointer Subtraction</h2> <p>Like pointer addition, we can subtract a value from the pointer variable. Subtracting any number from a pointer will give an address. The formula of subtracting value from the pointer variable is given below:</p> <pre> new_address= current_address - (number * size_of(data type)) </pre> <h3>32-bit</h3> <p>For 32-bit int variable, it will subtract 2 * number.</p> <h3>64-bit</h3> <p>For 64-bit int variable, it will subtract 4 * number.</p> <p>Let&apos;s see the example of subtracting value from the pointer variable on 64-bit architecture.</p> <pre> #include int main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p-3; //subtracting 3 from pointer variable printf(&apos;After subtracting 3: Address of p variable is %u 
&apos;,p); return 0; } </pre> <p> <strong>Output</strong> </p> <pre> Address of p variable is 3214864300 After subtracting 3: Address of p variable is 3214864288 </pre> <p>You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the previous address value.</p> <p>However, instead of subtracting a number, we can also subtract an address from another address (pointer). This will result in a number. It will not be a simple arithmetic operation, but it will follow the following rule.</p> <p>If two pointers are of the same type,</p> <pre> Address2 - Address1 = (Subtraction of two addresses)/size of data type which pointer points </pre> <p>Consider the following example to subtract one pointer from an another.</p> <pre> #include void main () { int i = 100; int *p = &amp;i; int *temp; temp = p; p = p + 3; printf(&apos;Pointer Subtraction: %d - %d = %d&apos;,p, temp, p-temp); } </pre> <p> <strong>Output</strong> </p> <pre> Pointer Subtraction: 1030585080 - 1030585068 = 3 </pre> <h2>Illegal arithmetic with pointers</h2> <p>There are various operations which can not be performed on pointers. Since, pointer stores address hence we must ignore the operations which may lead to an illegal address, for example, addition, and multiplication. A list of such operations is given below.</p> <ul> <li>Address + Address = illegal</li> <li>Address * Address = illegal </li> <li>Address % Address = illegal</li> <li>Address / Address = illegal</li> <li>Address &amp; Address = illegal</li> <li>Address ^ Address = illegal</li> <li>Address | Address = illegal</li> <li> ~Address = illegal</li> </ul> <h2>Pointer to function in C</h2> <p>As we discussed in the previous chapter, a pointer can point to a function in C. However, the declaration of the pointer variable must be the same as the function. Consider the following example to make a pointer pointing to the function. <pre> #include int addition (); int main () { int result; int (*ptr)(); ptr = &amp;addition; result = (*ptr)(); printf(&apos;The sum is %d&apos;,result); } int addition() { int a, b; printf(&apos;Enter two numbers?&apos;); scanf(&apos;%d %d&apos;,&amp;a,&amp;b); return a+b; } </pre> </p><p> <strong>Output</strong> </p> <pre> Enter two numbers?10 15 The sum is 25 </pre> <h2>Pointer to Array of functions in C</h2> <p>To understand the concept of an array of functions, we must understand the array of function. Basically, an array of the function is an array which contains the addresses of functions. In other words, the pointer to an array of functions is a pointer pointing to an array which contains the pointers to the functions. Consider the following example.</p> <pre> #include int show(); int showadd(int); int (*arr[3])(); int (*(*ptr)[3])(); int main () { int result1; arr[0] = show; arr[1] = showadd; ptr = &amp;arr; result1 = (**ptr)(); printf(&apos;printing the value returned by show : %d&apos;,result1); (*(*ptr+1))(result1); } int show() { int a = 65; return a++; } int showadd(int b) { printf(&apos;
Adding 90 to the value returned by show: %d&apos;,b+90); } </pre> <p> <strong>Output</strong> </p> <pre> printing the value returned by show : 65 Adding 90 to the value returned by show: 155 </pre> <hr></5;>

C'de Azaltma İşaretçisi

Arttırma gibi, bir işaretçi değişkenini de azaltabiliriz. Bir işaretçiyi azaltırsak önceki konumu işaret etmeye başlayacaktır. İşaretçiyi azaltma formülü aşağıda verilmiştir:

 new_address= current_address - i * size_of(data type) 

32 bit

32 bitlik int değişkeni için 2 bayt azaltılacaktır.

64 bit

64 bit int değişkeni için 4 bayt azaltılacaktır.

64 bit işletim sisteminde işaretçi değişkeninin azaltılması örneğini görelim.

 #include void main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p-1; printf(&apos;After decrement: Address of p variable is %u 
&apos;,p); // P will now point to the immidiate previous location. } 

Çıktı

 Address of p variable is 3214864300 After decrement: Address of p variable is 3214864296 

C İşaretçisi Ekleme

Pointer değişkenine bir değer ekleyebiliriz. İşaretçiye değer ekleme formülü aşağıda verilmiştir:

 new_address= current_address + (number * size_of(data type)) 

32 bit

32 bit int değişkeni için 2 * sayı ekleyecektir.

64 bit

64-bit int değişkeni için 4* sayı ekleyecektir.

64 bit mimaride pointer değişkenine değer ekleme örneğini görelim.

 #include int main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p+3; //adding 3 to pointer variable printf(&apos;After adding 3: Address of p variable is %u 
&apos;,p); return 0; } 

Çıktı

 Address of p variable is 3214864300 After adding 3: Address of p variable is 3214864312 

Gördüğünüz gibi p'nin adresi 3214864300. Ancak p değişkenine 3 eklendikten sonra 3214864312 yani 4*3=12 artış oluyor. 64 bit mimari kullandığımız için 12 artıyor. Ama 32 bit mimari kullanıyorsak sadece 6’ya çıkıyor yani 2*3=6. Tam sayı değeri 32 bit işletim sisteminde 2 baytlık bellek kaplar.

C İşaretçisi Çıkarma

İşaretçi eklemede olduğu gibi işaretçi değişkeninden bir değer çıkarabiliriz. Bir işaretçiden herhangi bir sayının çıkarılması bir adres verecektir. İşaretçi değişkeninden değer çıkarma formülü aşağıda verilmiştir:

 new_address= current_address - (number * size_of(data type)) 

32 bit

32 bitlik int değişkeni için 2 * sayısını çıkaracaktır.

64 bit

64-bit int değişkeni için 4* sayısını çıkaracaktır.

64 bit mimaride pointer değişkeninden değer çıkarma örneğini görelim.

 #include int main(){ int number=50; int *p;//pointer to int p=&amp;number;//stores the address of number variable printf(&apos;Address of p variable is %u 
&apos;,p); p=p-3; //subtracting 3 from pointer variable printf(&apos;After subtracting 3: Address of p variable is %u 
&apos;,p); return 0; } 

Çıktı

model örnekleridir
 Address of p variable is 3214864300 After subtracting 3: Address of p variable is 3214864288 

Pointer değişkeninden 3 çıkarıldığında önceki adres değerinden 12 (4*3) daha az olduğunu görebilirsiniz.

Ancak bir sayıyı çıkarmak yerine, bir adresi başka bir adresten (işaretçi) de çıkarabiliriz. Bu bir sayıyla sonuçlanacaktır. Basit bir aritmetik işlem olmayacak ancak aşağıdaki kurala uyacaktır.

İki işaretçi aynı türdense,

 Address2 - Address1 = (Subtraction of two addresses)/size of data type which pointer points 

Bir işaretçiyi diğerinden çıkarmak için aşağıdaki örneği inceleyin.

 #include void main () { int i = 100; int *p = &amp;i; int *temp; temp = p; p = p + 3; printf(&apos;Pointer Subtraction: %d - %d = %d&apos;,p, temp, p-temp); } 

Çıktı

 Pointer Subtraction: 1030585080 - 1030585068 = 3 

İşaretçilerle yasa dışı aritmetik

İşaretçiler üzerinde gerçekleştirilemeyen çeşitli işlemler vardır. İşaretçi adresi sakladığından, toplama ve çarpma gibi yasadışı bir adrese yol açabilecek işlemleri göz ardı etmeliyiz. Bu tür işlemlerin bir listesi aşağıda verilmiştir.

  • Adres + Adres = yasa dışı
  • Adres * Adres = yasa dışı
  • Adres % Adres = geçersiz
  • Adres / Adres = yasa dışı
  • Adres ve Adres = yasa dışı
  • Adres ^ Adres = yasa dışı
  • Adres | Adres = yasa dışı
  • ~Adres = yasa dışı

C'de işlev görecek işaretçi

Önceki bölümde tartıştığımız gibi, bir işaretçi C'de bir işlevi işaret edebilir. Ancak işaretçi değişkeninin bildirimi, işlevle aynı olmalıdır. Fonksiyona işaret eden bir işaretçi yapmak için aşağıdaki örneği göz önünde bulundurun.

 #include int addition (); int main () { int result; int (*ptr)(); ptr = &amp;addition; result = (*ptr)(); printf(&apos;The sum is %d&apos;,result); } int addition() { int a, b; printf(&apos;Enter two numbers?&apos;); scanf(&apos;%d %d&apos;,&amp;a,&amp;b); return a+b; } 

Çıktı

 Enter two numbers?10 15 The sum is 25 

C'deki Fonksiyon Dizisinin İşaretçisi

Fonksiyon dizisi kavramını anlamak için fonksiyon dizisini anlamamız gerekir. Temel olarak, işlevin dizisi, işlevlerin adreslerini içeren bir dizidir. Başka bir deyişle, bir işlev dizisinin işaretçisi, işlevlerin işaretçilerini içeren bir diziye işaret eden bir işaretçidir. Aşağıdaki örneği düşünün.

 #include int show(); int showadd(int); int (*arr[3])(); int (*(*ptr)[3])(); int main () { int result1; arr[0] = show; arr[1] = showadd; ptr = &amp;arr; result1 = (**ptr)(); printf(&apos;printing the value returned by show : %d&apos;,result1); (*(*ptr+1))(result1); } int show() { int a = 65; return a++; } int showadd(int b) { printf(&apos;
Adding 90 to the value returned by show: %d&apos;,b+90); } 

Çıktı

 printing the value returned by show : 65 Adding 90 to the value returned by show: 155