【问题标题】:question regarding the *p and the p inside the for loop关于 for 循环内的 *p 和 p 的问题
【发布时间】:2019-09-29 17:14:21
【问题描述】:

我对以下代码有两个问题,尤其是int sum(const int *begin, const int *end) 函数。我不明白的是为什么我们将p 分配为指向不可变常量的指针,即开始。但是,在sum() 内的for 循环中也有++p?为什么是++p 而不是++*p?为什么是p!=end 而不是*p!= end

我读到的是:“const int *p 中,*p(指向的内容)是恒定的,但p 不是恒定的。

我不太明白这个函数中*pp的用法有什么区别。

我的第二个问题是:在int sum(...)的for循环中声明const在:const int *p = begin的原因是什么?是不是因为在int sum(...) 的签名中,有这个const 被声明为:const int *p = begin? IE。是不是因为 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;
}

【问题讨论】:

  • 你是从什么来源学习 C++ 的?
  • p 是一个包含地址的指针。 *p 是存储在该地址中的值。指针由int *p; 声明。 ++p 增加地址。 ++*p 增加值。
  • 正如您已经提到的,const int *p 将指向一个 const int,这意味着我们只能移动指针而不能更改指向的值。函数 sum 应该只计算给定范围内的总和,并且不应该改变数组的值,因此 const int* 用于确保这一点。
  • 你好,但是我可以知道在这种情况下增加地址是什么意思吗?因为不是地址像 0x321F ... 或类似的东西吗?在这里将地址增加 1 是什么意思?喜欢++p?所以 0x321F +1 ?然后再 +1?
  • 如果p 是指向数组a 中元素i 的指针,那么p+1 是指向a[i+1] 的指针(即递增它使其指向下一个元素)。

标签: c++ pointers constants


【解决方案1】:

提醒一下,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 处的整数(提供 Big Endian 布局)。

递增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 字节边界

【讨论】:

  • 你好,但是我可以知道在这种情况下增加地址是什么意思吗?因为不是地址像 0x321F ... 或类似的东西吗?在这里将地址增加 1 是什么意思?喜欢++p?所以 0x321F +1 ?然后再 +1?
  • p 存储某物的地址,对吗?那么 ++p 是做什么的呢?我认为这会将地址增加1?所以0x321F + 1?但这等于什么?
  • 内存地址只是一个数字。十六进制只是常用来表示内存地址的符号。我相信 0x321F + 1 会是 0x3220?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多