различия в C: * source ++, (* source) ++, * (source) ++ - PullRequest
0 голосов
/ 06 марта 2019

Есть ли разница между этими указателями? Что именно здесь происходит для каждого звонка.

  1. * p ++
  2. (* p) ++,
  3. * (р) ++

Ответы [ 3 ]

1 голос
/ 06 марта 2019

крошечная тестовая программа.

#include <stdio.h>

int main(void) {
    char z[] = "World";
    char n[] = "Something";
    char *x = "Hello!!";


    while(*x) printf("%c", *x++);
    printf("\n");
    x = z;
    while(*x) printf("%c", (*x)++);
    printf("\n");
    x = n;
    while(*x) printf("%c", *(x)++);
    printf("\n");
    return 0;
}

, поэтому *x++ разыменовывает указатель, затем увеличивает указатель (*x)++ - только увеличивает ссылочный объект.*(x)++ == *x++

ИМО вместо того, чтобы просить попробовать себя.Вы узнаете что-то https://ideone.com/bliza0

1 голос
/ 07 марта 2019

1 и 3 одинаковы.

Помните, что как постфиксные, так и унарные формы ++ и -- имеют результат и побочный эффект :

  • Результатом x++ является текущее значение x - в качестве побочного эффекта x увеличивается на 1 (если x - указатель, этоувеличивается для указания на следующий объект в последовательности);

  • Результатом ++x является текущее значение x плюс 1 - какпобочный эффект, x увеличивается на 1 (если x - указатель, результатом является адрес следующего объекта в последовательности, а x обновляется, чтобы указывать на следующий объект в последовательности);

Обе формы -- работают одинаково, за исключением того, что значение уменьшается на 1 - если это указатель, то он указывает на предыдущий объект в последовательности.

Когда вы бросаете разыменования указателя в микс, вы получаете следующее:

  • Выражение *p++ анализируется как *(p++) (как и *(p)++),Результатом *p++ является текущее значение *p (значение вещи, на которую в данный момент указывает p).Как побочный эффект, p увеличивается для указания на следующий объект того же типа в последовательности (IOW, следующий элемент массива);

  • Выражение (*p)++ анализируется как написаноРезультатом (*p)++ является текущее значение *p.Как побочный эффект, *p увеличивается на 1. То есть обновляется значение объекта, на который указывает указатель, а не указатель.

  • Выражение ++*p анализируется как ++(*p).Результатом ++*p является текущее значение *p плюс 1. В качестве побочного эффекта *p увеличивается на 1.

  • Выражение *++p анализируется как*(++p).Результатом *++p является значение объекта , следующего за объектом, на который в данный момент указывает p.В качестве побочного эффекта p увеличивается, чтобы указывать на следующий объект.

Предполагается следующее объявление:

int a[] = {1, 2, 3, 4};
int *p = a;   

После этих строк значениеp - это &a[0].Таким образом, учитывая выражение

x = *p++;

результат из *p++ равен 1 (значение вещи p в данный момент указывает на), которое присваивается x.Побочный эффект заключается в том, что p обновляется до значения a[1].

Затем мы выполняем

x = (*p)++;  

Результат из (*p)++ - это значение вещи, на которую p указывает в данный момент (если p указывает на a[1], тогда значение равно 2), которое присваивается x.Как побочный эффект, вещь, на которую указывает p, увеличивается (если p указывает на a[1], то значение a[1] теперь равно 3).

Мы выполняем

x = ++*p;    

Результатом ++*p является значение вещи, p указывает на плюс 1, и в результате вещь, на которую p указывает, являетсяувеличивается (если p указывает на a[1], то значение a[1] + 1 равно 4, которое присваивается x, а значение a[1] теперь равно 4).

Наконец, мы выполняем

x = *++p;

Результатом *++p является значение объекта , следующего за объекта, на который в данный момент указывает p, и p увеличиваетсячтобы указать на этот объект (если p указывает на a[1], то значение a[2] (3) записывается в x, а p обновляется, чтобы указывать на a[2]).

Опять же, -- работает так же, только в другом направлении.

0 голосов
/ 06 марта 2019

*source++ будет проанализировано как *(source++) из-за более высокого приоритета из ++ над * оператором. Он увеличит указатель на 1, а затем разыменует указатель.


Для понимания поведения сначала позвольте мне объяснить, как работает оператор постинкрементной обработки. Когда вы делаете

int i = 0;
int j = i++;

тогда это означает, что значением выражения i++ будет значение операнда i. В этом случае это будет 0. Значение i будет увеличено как побочный эффект. Смотрите цитату из черновика

n1570 - §6.5.2.4 / 2:

Результатом оператора postfix ++ является значение операнда . Как побочный эффект, значение объекта операнда увеличивается (то есть к нему добавляется значение 1 соответствующего типа). См. Обсуждение аддитивных операторов и составного присваивания для получения информации об ограничениях, типах и преобразованиях, а также о влиянии операций на указатели. Вычисление значения результата выполняется до появления побочного эффекта обновления сохраненного значения операнда .

В случае *source++ компилятор проанализирует его как *(source++). Результатом выражения source++ является значение source. Таким образом, текущий указатель (на адрес source указывает перед побочным эффектом) будет разыменован, а затем будет выполнен побочный эффект на source.

(*source)++ сначала разыменует указатель, а затем увеличивает разыменованное значение на 1.

*(source)++ эквивалентно первому случаю.


Я прошу прощения за неправильный ответ и оставляю неправильный ответ с забастовками, чтобы будущие читатели извлекли урок, если кто-нибудь придет к тому же неправильному выводу, что и я. Спасибо @interjay и @pmg за поправку. Я очень рад, что вы, ребята, являетесь частью этого сообщества и вносите свой вклад в это сообщество своими острыми глазами и умом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...