logo

Арифметика вказівника в C

Ми можемо виконувати над покажчиками арифметичні операції, такі як додавання, віднімання тощо. Однак, оскільки ми знаємо, що вказівник містить адресу, результат арифметичної операції, виконаної над вказівником, також буде вказівником, якщо інший операнд має тип цілого числа. При відніманні покажчика від покажчика результатом буде ціле число. Над вказівником на мові C можливі наступні арифметичні операції:

  • Приріст
  • Декремент
  • Доповнення
  • Віднімання
  • Порівняння

Збільшення покажчика в C

Якщо ми збільшимо вказівник на 1, вказівник почне вказувати на найближче місце розташування. Це дещо відрізняється від загальної арифметики, оскільки значення вказівника буде збільшено відповідно до розміру типу даних, на який вказує вказівник.

Ми можемо пройти по масиву, використовуючи операцію збільшення вказівника, який постійно вказуватиме на кожен елемент масиву, виконуватиме над ним певну операцію та оновлюватиметься в циклі.

Правило збільшення покажчика наведено нижче:

 new_address= current_address + i * size_of(data type) 

Де i — число, на яке збільшується вказівник.

32-розрядний

Для 32-розрядної змінної int вона буде збільшена на 2 байти.

64-розрядний

Для 64-розрядної змінної int вона буде збільшена на 4 байти.

Давайте розглянемо приклад збільшення змінної покажчика на 64-бітній архітектурі.

 #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; } 

Вихід

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

Обхід масиву за допомогою покажчика

 #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

Подібно до збільшення, ми можемо зменшувати змінну-вказівник. Якщо ми зменшимо покажчик, він почне вказувати на попереднє розташування. Формула зменшення покажчика наведена нижче:

 new_address= current_address - i * size_of(data type) 

32-розрядний

Для 32-розрядної змінної int вона буде зменшена на 2 байти.

64-розрядний

Для 64-розрядної змінної int вона буде зменшена на 4 байти.

Розглянемо приклад зменшення змінної покажчика на 64-розрядній ОС.

 #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. } 

Вихід

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

C Додавання вказівника

Ми можемо додати значення до змінної покажчика. Формула додавання значення до покажчика наведена нижче:

java дорівнює
 new_address= current_address + (number * size_of(data type)) 

32-розрядний

Для 32-розрядної змінної int додасться число 2 *.

64-розрядний

Для 64-розрядної змінної int додасться число 4 *.

Давайте розглянемо приклад додавання значення до змінної покажчика на 64-розрядній архітектурі.

 #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; } 

Вихід

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

Як бачите, адреса p дорівнює 3214864300. Але після додавання 3 зі змінною p, це 3214864312, тобто 4*3=12 приростів. Оскільки ми використовуємо 64-бітну архітектуру, вона збільшується на 12. Але якщо ми використовуємо 32-бітну архітектуру, вона збільшується лише до 6, тобто 2*3=6. Оскільки ціле значення займає 2-байтну пам'ять у 32-бітній ОС.

C Віднімання вказівника

Подібно до додавання покажчика, ми можемо відняти значення від змінної покажчика. Віднімання будь-якого числа від вказівника дасть адресу. Формула віднімання значення від змінної покажчика наведена нижче:

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

32-розрядний

Для 32-розрядної змінної int вона відніме 2 * число.

64-розрядний

Для 64-розрядної змінної int вона відніме 4 * число.

Давайте розглянемо приклад віднімання значення від змінної покажчика на 64-бітній архітектурі.

 #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; } 

Вихід

 Address of p variable is 3214864300 After subtracting 3: Address of p variable is 3214864288 

Ви можете побачити, що після віднімання 3 від змінної покажчика це на 12 (4*3) менше попереднього значення адреси.

Однак замість віднімання числа ми також можемо відняти адресу від іншої адреси (вказівника). Це призведе до числа. Це не буде проста арифметична операція, але вона буде відповідати такому правилу.

Якщо два покажчики одного типу,

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

Розглянемо наступний приклад, щоб відняти один покажчик від іншого.

пріоритетна черга
 #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); } 

Вихід

 Pointer Subtraction: 1030585080 - 1030585068 = 3 

Незаконна арифметика з покажчиками

Існують різні операції, які не можна виконувати над покажчиками. Оскільки покажчик зберігає адресу, ми повинні ігнорувати операції, які можуть призвести до неправильної адреси, наприклад, додавання та множення. Перелік таких операцій наведено нижче.

  • Адреса + Адреса = незаконно
  • Адреса * Адреса = незаконно
  • Адреса % Адреса = незаконно
  • Адреса / Адреса = незаконно
  • Адреса та адреса = незаконно
  • Адреса ^ Адреса = незаконно
  • Адреса | Адреса = незаконно
  • ~Адреса = нелегальна

Покажчик на функцію в C

Як ми обговорювали в попередньому розділі, покажчик може вказувати на функцію в C. Однак оголошення змінної покажчика має бути таким самим, як і функція. Розглянемо наступний приклад, щоб створити покажчик, що вказує на функцію.

 #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; } 

Вихід

 Enter two numbers?10 15 The sum is 25 

Покажчик на масив функцій у C

Щоб зрозуміти концепцію масиву функцій, ми повинні зрозуміти масив функцій. По суті, масив функції — це масив, який містить адреси функцій. Іншими словами, вказівник на масив функцій - це вказівник на масив, який містить покажчики на функції. Розглянемо наступний приклад.

 #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); } 

Вихід

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