logo

Аритметика на указателя в C

Можем да извършваме аритметични операции върху указателите като добавяне, изваждане и т.н. Но тъй като знаем, че указателят съдържа адреса, резултатът от аритметична операция, извършена върху указателя, също ще бъде указател, ако другият операнд е от тип цяло число. При изваждане на указател от указател резултатът ще бъде цяло число. Следните аритметични операции са възможни върху показалеца на език C:

  • Увеличаване
  • Намаляване
  • Допълнение
  • Изваждане
  • Сравнение

Увеличаване на показалеца в C

Ако увеличим указател с 1, указателят ще започне да сочи към непосредственото следващо местоположение. Това е малко по-различно от общата аритметика, тъй като стойността на указателя ще се увеличи с размера на типа данни, към който указателят сочи.

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

Правилото за увеличаване на показалеца е дадено по-долу:

 new_address= current_address + i * size_of(data type) 

Където i е числото, с което указателят се увеличава.

32-битов

За 32-битова int променлива, тя ще бъде увеличена с 2 байта.

runas в powershell

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 добавяне на указател

Можем да добавим стойност към променливата указател. Формулата за добавяне на стойност към указателя е дадена по-долу:

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

Изход

java уроци
 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