此示例是否应该更改内存地址而不是该内存地址的值?

should this example not alter the memory address rather than the value at that memory address?

本文关键字:内存 地址 是否      更新时间:2023-10-16

在我正在阅读的一本书中,C++从头开始,在第 113 页上,作者创建了一个字符数组:

myString[80];

然后他使用一个函数来复制一些 charectars:

strcpy(myString,"Hello there");

然后他创建一个指向数组的指针:

*p1 = myString;

然后他使用偏移量并在该偏移量处断言一个值:

p1[4]='c';

我的问题是,P1 是一个指针,所以它是一个内存地址,而 4 的偏移量给了他前面 4 个空格的内存地址,所以这意味着他将字母"c"断言到内存地址而不是存储在该地址的值。不应该是:

*(p1[4])='c';

基本上,为什么 *(P1 + 4( 需要取消引用,而 P1[4] 不需要?

我试图理解这一点,唯一对我来说有意义的事情是方括号是否充当星号来取消引用指针。这是正确的还是有其他原因为什么p1[4]不需要取消引用?

然后他创建一个指向数组的指针:

*p1 = myString;

假设,你的意思是p1是用 声明和初始化的;

char *p1 = myString;

那么你的解释是错误的。p1是指向char的指针,而不是指向数组的指针。

在此定义中,myString是(之前在您的问题中声明的(char数组的名称。 在初始化中

char *p1 = myString;

名称myString将转换为指针。 该指针将具有值&myString[0](即myString中第一个字符的地址(。 这就是p1将获得的价值。

声明

p1[4] = 'c';

然后将myString的第五个字符(因为索引从零开始(设置为'c'。 因此,结果是myString[4]更改为值'c'。 这意味着(前 11 个字符(myString将被"Hellc there"

假设上述情况,表达式*(p1[4])='c'将不会编译,因为(p1[4])char类型,并且不能使用*运算符取消引用。

在语义上,在表达式中p1[4]等效于*(p1 + 4)。 由于p1初始化为等于&myString[0]p1[4]也等价于myString[4]*(myString + 4)

注意:如果*(p1[4])='c'在您的代码中有效,那么p1[4] = 'c'将无效,这表明我对p1的声明和初始化的假设是正确的 - 尽管您省略了此类信息。

p1 + 4将是4位以上的内存地址。

表达式p1[4](完全等同于*(p1+4)(称为左值表达式。 我们说左值表达式指定一个内存位置。 换句话说,左值表达式是内存位置本身的同义词。 您始终可以在 lvalue 表达式上使用&address-of 运算符,这将为您提供指向内存位置的指针。

左值表达式将继续以以下三种可能的方式之一使用:

  1. 将值存储在指定的内存位置,或
  2. 从指定的内存位置检索值,或
  3. 都不是。

没有特殊的语法来区分这三种情况;相反,它取决于左值表达式所属的较大表达式。 例如,应用&运算符是情况 3; 出现在赋值运算符=左侧的是情况 1。 大多数其他用法属于情况 2。

p1[4]

被视为*(p1 + 4),即"与 p1 偏移量为 4 的值"。

同样,当您声明字符数组时:

myString[80]

myString 是指向数组的指针(它指向第一个元素(。因此,当您执行myString[4]时,它也被视为*(myString + 4)

*(p1[4])意味着*(*(p1 + 4))