Разница между *ptr += 1 и * ptr++ в C



Я только начал изучать C, и когда я делал один пример о передаче указателя на указатель в качестве параметра функции, я нашел проблему.



это мой пример кода :



#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int* allocateIntArray(int* ptr, int size){
if (ptr != NULL){
for (int i = 0; i < size; i++){
ptr[i] = i;
}
}
return ptr;
}

void increasePointer(int** ptr){
if (ptr != NULL){
*ptr += 1; /* <----------------------------- This is line 16 */
}
}

int main()
{
int* p1 = (int*)malloc(sizeof(int)* 10);
allocateIntArray(p1, 10);

for (int i = 0; i < 10; i++){
printf("%dn", p1[i]);
}

increasePointer(&p1);
printf("%dn", *p1);
p1--;
free(p1);
fgets(string, sizeof(string), stdin);
return 0;
}


проблема возникает в строке 16, когда я изменить *ptr+=1 to *ptr++. Ожидаемый результат должен быть весь массив и номер 1, но когда я использую *ptr++ результат 0.



есть ли разница между +=1 и ++? Я думал, что оба они являются тот же.

1012   5  

5 ответов:

разница обусловлена приоритетом оператора.

оператор постинкремента ++ имеет более высокий приоритет, чем оператор разыменования *. Так что *ptr++ эквивалентно *(ptr++). Другими словами, приращение post изменяет указатель, а не то, на что он указывает.

оператор присваивания += имеет более низкий приоритет, чем оператор разыменования *, Так что *ptr+=1 эквивалентно (*ptr)+=1. Другими словами, оператор присваивания изменяет значение, на которое указывает указатель, и не изменяет сам указатель.

порядок приоритета для 3 операторов, участвующих в вашем вопросе, следующий:

пост-инкремент ++ > разыменования * > задание +=

вы можете проверить это страница для получения дополнительной информации по этой теме.

при разборе выражения оператор, который указан в какой-либо строке, будет связан с его аргументами более плотно (как если бы скобками), чем любой оператор, который указан в строке ниже оно. Например, выражение *p++ анализируется как *(p++), а не (*p)++.

короче говоря, чтобы выразить это задание *ptr+=1 С помощью оператора post-increment вам нужно добавить скобки к оператору разыменования, чтобы дать этой операции приоритет над ++ в этой (*ptr)++

давайте применим скобки, чтобы показать порядок действий

a + b / c
a + (b/c)

давайте сделаем это снова с

*ptr   += 1
(*ptr) += 1

и снова

*ptr++
*(ptr++)
  • на *ptr += 1, мы увеличиваем значение переменной наш указатель точки для.
  • на *ptr++, мы увеличиваем указатель после весь наш оператор (строка кода) выполняется, и возвращает ссылку на переменную наш указатель точки для.

последняя позволяет делать такие вещи, как:

for(int i = 0; i < length; i++)
{
    // Copy value from *src and store it in *dest
    *dest++ = *src++;

    // Keep in mind that the above is equivalent to
    *(dest++) = *(src++);
}

это общий метод, используемый для копирования src массив в другой dest массив.

очень хороший вопрос.

В K&R "C язык программирования ""5.1 указатели и адреса", мы можем получить ответ на это.

"унарные операторы * и & связываются более плотно, чем арифметические операторы"

*ptr += 1      //Increment what ptr points to.

" унарные операторы, такие как * и ++ associate справа налево."

*ptr++        //Increment prt instead of what ptr point to.

//он работает как *(ptr++).

правильный путь:

(*ptr)++      //This will work.

* ptr += 1: приращение данных, на которые указывает ptr. * ptr++: указатель приращения, который указывает на следующую ячейку памяти вместо данных, на которые указывает указатель.

Comments

    Ничего не найдено.