Непонимание арифметики указателей с ++ и - - PullRequest
5 голосов
/ 21 ноября 2011

Итак, я узнаю об указателях через http://cplusplus.com/doc/tutorial/pointers/, и я ничего не понимаю в секции арифметики указателей. Может кто-то прояснить ситуацию или указать мне учебник по этому вопросу, который я могу лучше понять.

Меня особенно смущают все скобки, такие как разница между *p++, (*p)++, *(p++) и т. Д.

Ответы [ 4 ]

4 голосов
/ 21 ноября 2011

*p++

Для этого ++ имеет более высокий приоритет, чем *, поэтому он увеличивает указатель на единицу, но извлекает значение в исходном местоположении, поскольку постинкремент возвращает указатель, а затем увеличивает его значение.

(*p)++

Это вызывает приоритет в другом направлении, поэтому сначала на указатель ссылаются, а затем значение в этом месте увеличивается на единицу (но возвращается значение в исходном месте указателя).

*(p++)

Этот объект увеличивает указатель первым, поэтому он действует так же, как и первый.

Важно отметить, что на величину увеличения указателя влияет тип указателя. По предоставленной вами ссылке:

char *mychar;
short *myshort;
long *mylong;

char имеет длину один байт, поэтому ++ увеличивает указатель на 1 (поскольку указатели указывают на начало каждого байта).

short имеет длину два байта, поэтому ++ увеличивает указатель на 2, чтобы указывать на начало следующего короткого, а не на начало следующего байта.

long имеет длину четыре байта, поэтому ++ увеличивает указатель на 4.

1 голос
/ 22 ноября 2011

Несколько лет назад я нашел полезным объяснение strcpy от Kernighan / Ritchie (сейчас у меня нет доступного текста, надеюсь, код точный): cpy_0, cpy_1, cpy_2 все эквивалентны strcpy:

char *cpy_0(char *t, const char *s)
{
    int i = 0;
    for ( ; t[i]; i++)
        t[i] = s[i];
    t[i] = s[i];
    i++;
    return t + i;
}
char *cpy_1(char *t, const char *s)
{
    for ( ; *s; ++s, ++t)
        *t = *s;
    *t = *s;
    ++t;
    return t;
}
char *cpy_2(char *t, const char *s)
{
    while (*t++ = *s++)
        ;
    return t;
}
0 голосов
/ 21 ноября 2011

Сначала вы должны понять, что делает инкремент поста;
Постинкремент увеличивает переменную на один НО выражение (p ++) возвращает исходное значение переменной, которая будет использоваться в остальной части выражения.

char   data[] = "AX12";
char* p;

p = data;
char* a = p++;

// a -> 'A'  (the original value of p was returned from p++ and assigned to a)
// p -> 'X'

p = data;   // reset;
char  l =  *(p++);

// l =  'A'. The (p++) increments the value of p. But returns the original
             value to be used in the remaining expression. Thus it is the
             original value that gets de-referenced by * so makeing l 'A'
// p -> 'X'

Теперь из-за приоритета оператора:

*p++ is equivalent to *(p++)

Наконец, у нас есть сложный:

p = data;
char m = (*p)++;

// m is 'A'. First we deference 'p' which gives us a reference to 'A'
//           Then we apply the post increment which applies to the value 'A' and makes it a 'B'
//           But we return the original value ('A') to be used in assignment to 'm'

// Note 1:   The increment was done on the original array
//           data[]  is now "BXYZ";
// Note 2:   Because it was the value that was post incremented p is unchaged.
// p -> 'B' (Not 'X')
0 голосов
/ 21 ноября 2011
*p++

Возвращает содержимое, * p , а затем увеличивает значение указателя (postincrement). Например:

int numbers[2];
int *p;
p = &numbers[0];
*p = 4;        //numbers[0] = 4;
*(p + 1) = 8;  //numbers[1] = 8;
int a = *p++;  //a = 4 (the increment takes place after the evaluation)
               //*++p would have returned 8 (a = 8)
int b = *p;    //b = 8 (p is now pointing to the next integer, not the initial one)

А о:

(*p)++

Увеличивает значение содержимого, * p = * p + 1; .

(p++); //same as p++

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

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