Różnica między * ptr + = 1 A * ptr++ w C

Właśnie zacząłem studiować C, i robiąc jeden przykład na temat przekazywania wskaźnika do wskaźnika jako parametru funkcji, znalazłem problem.

Oto mój przykładowy kod:

#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("%d\n", p1[i]);
    }

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

Problem występuje w linii 16, kiedy zmieniam *ptr+=1 na *ptr++. Oczekiwanym wynikiem powinna być cała tablica i liczba 1, ale gdy używam *ptr++ wynik jest 0.

Czy jest jakaś różnica między +=1 a ++? Myślałem, że oba są takie same.

Author: alcedine, 2016-02-10

5 answers

Różnica wynika z pierwszeństwa operatora.

Operator post-incrementowy ++ ma wyższy priorytet niż operator dereferencyjny *. Więc {[2] } jest równoważne *(ptr++). Innymi słowy, przyrost post modyfikuje wskaźnik, a nie to, na co wskazuje.

Operator przypisania += ma niższy priorytet niż operator dereferencji *, więc *ptr+=1 jest równoważne (*ptr)+=1. Innymi słowy, operator przypisania modyfikuje wartość, na którą wskazuje wskaźnik, i robi nie zmieniaj samego wskaźnika.

 282
Author: user3386109,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 01:29:20

Kolejność pierwszeństwa dla 3 operatorów zaangażowanych w twoje pytanie jest następująca:

Post-increment ++ > dereference * > assignment +=

Możesz sprawdzić tę stronę , aby uzyskać więcej informacji na ten temat.

Podczas parsowania wyrażenia operator, który jest wymieniony w wierszu, będzie związany z jego argumentami mocniej (jakby nawiasami) niż jakikolwiek operator, który jest wymieniony w wierszu poniżej. Na przykład wyrażenie *p++ jest przetwarzane jako *(p++), a nie jako (*p)++.

W skrócie, aby wyrazić to przypisanie {[6] } za pomocą operatora post-increment należy dodać nawiasy do operatora dereferencji, aby nadać tej operacji pierwszeństwo przed ++ jak w tym (*ptr)++

 21
Author: Younes Regaieg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 16:27:47

Zastosujmy nawiasy, aby pokazać kolejność operacji

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

Zróbmy to jeszcze raz

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

I znowu z

*ptr++
*(ptr++)
  • W *ptr += 1, zwiększamy wartość zmiennej nasz wskaźnik punktów do.
  • w *ptr++ zwiększamy wskaźnik po wykonaniu całego naszego polecenia (linii kodu) i zwracamy odniesienie do zmiennej, do której wskazuje nasz wskaźnik .

Ten ostatni pozwala na robienie rzeczy like:

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

Jest to popularna metoda używana do skopiowania tablicy src do innej tablicy dest.

 7
Author: Mateen Ulhaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 17:25:42

Bardzo dobre pytanie.

W K & R "C programming language ""5.1 Pointers and Addresses", możemy uzyskać na to odpowiedź.

"operatory jednoargumentowe * i & wiążą się mocniej niż operatory arytmetyczne"

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

"operatory jednoargumentowe, takie jak * i++, kojarzą od prawej do lewej ."

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

//działa jak * (ptr++).

Prawidłowy sposób to:

(*ptr)++      //This will work.
 3
Author: Nick.Sang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 03:58:11

*ptr + = 1: Dane przyrostowe, na które wskazuje ptr. * ptr++: wskaźnik Przyrostowy, który wskazuje na następną lokalizację pamięci zamiast danych, na które wskazuje wskaźnik.

 2
Author: user5787482,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 01:52:14