Разница между *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 и ++? Я думал, что оба они являются тот же.
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