вопрос относительно * р и р внутри цикла for - PullRequest
0 голосов
/ 29 сентября 2019

У меня два вопроса по поводу следующего кода, в частности, функция int sum(const int *begin, const int *end). Я не понимаю, почему мы присваиваем p как указатель на неизменяемую константу, т.е. начинаем. Но тогда у нас также есть ++p в цикле for внутри sum()? Почему это ++p, а не ++*p? И почему это p!=end, а не *p!= end?

Я читал, что: " В const int *p, *p (содержимое, на которое указывают) является постоянным, но p не является константой."

Я не совсем понимаю разницу между использованием *p и p в этой функции.

Мой второй вопрос:В чем причина объявления const в: const int *p = begin в цикле for int sum(...)? Это потому, что в подписи int sum(...) объявлено это const для: const int *p = begin? То есть это потому, что begin объявляется как нечто неизменяемое - поэтому в цикле for мы должны объявить begin - неизменную константу, на которую указывает указатель *p?

/* Function to compute the sum of a range of an array (SumArrayRange.cpp) */
#include <iostream>
using namespace std;

// Function prototype
int sum(const int *begin, const int *end);

// Test Driver
   int main() {
   int a[] = {8, 4, 5, 3, 2, 1, 4, 8};
   cout << sum(a, a+8) << endl;        // a[0] to a[7]
   cout << sum(a+2, a+5) << endl;      // a[2] to a[4]
   cout << sum(&a[2], &a[5]) << endl;  // a[2] to a[4]
}

// Function definition
// Return the sum of the given array of the range from
// begin to end, exclude end.
int sum(const int *begin, const int *end) {
    int sum = 0;
    for (const int *p = begin; p != end; ++p) {
        sum += *p;
    }
    return sum;
}

1 Ответ

0 голосов
/ 29 сентября 2019

Напоминаем, что таблица const и указатели:

int * p -- Pointer to a mutable (read/write) location. Pointer and target data may be modified.
int const * p -- Pointer to read only location.  The data at the location constant, read-only.
int * const p -- Constant pointer to read/write location.  Pointer can't be changed, but data at location may be changed.  
int const * const p -- Constant pointer to constant data.  Neither pointer nor data may be changed.

В объявлении:

int sum(const int *begin, const int *end);  

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

Редактировать 1: увеличение указателя
Давайте назначим указатель, p, значение 0x12.
Целые числа будут иметь длину 4 байта:

     +---+  
p -> | 1 | 0x12
     +---+  
     | 2 | 0x13
     +---+  
     | 3 | 0x14
     +---+  
     | 4 | 0x15
     +---+
     | 0 | 0x16
     +---+  
     | 6 | 0x17
     +---+  
     | 1 | 0x18
     +---+  
     | 9 | 0x19
     +---+  

Целое число в *p == 1234 (предоставляется макет с прямым порядком байтов).

При увеличении p будет получен адрес: 0x12 + 1 * sizeof(int) или
0x12 + 1 * (4) == 0x16.

          +---+  
p ->      | 1 | 0x12
          +---+  
          | 2 | 0x13
          +---+  
          | 3 | 0x14
          +---+  
          | 4 | 0x15
          +---+
p + 1 ->  | 0 | 0x16
          +---+  
          | 6 | 0x17
          +---+  
          | 1 | 0x18
          +---+  
          | 9 | 0x19
          +---+  

Редактировать 2: Выравнивание
С этой точки зрения существует проблема выравнивания .
Предположим, что процессор 32-битный. Размер внутреннего регистра (слова) составляет 32 бита (4 октета). Процессор определен для извлечения 32-битной памяти.

Давайте сохраним целые числа по адресам 4, 8, 12 и 16. Двоичное представление этих адресов:

0000 0100 -- 4
0000 1000 -- 8
0000 1100 -- 12
0001 0000 -- 16

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

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