简体   繁体   English

这个例子不应该改变存储地址而不是改变那个存储地址的值吗?

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

In a book I am reading, C++ from scratch, on page 113 the writer creates a char array: 在我从零开始使用C ++的书中,第113页,作者创建了一个char数组:

myString[80];

then he uses a function that copies some charectars: 然后他使用了一个复制一些特征的函数:

strcpy(myString,"Hello there");

then he creates a pointer to the array: 然后他创建一个指向数组的指针:

*p1 = myString;

then he uses an offset and assings a value at that offset: 然后他使用一个偏移量并在该偏移量处赋值:

p1[4]='c';

my question is, p1 is a pointer so it is a memory address, and the offset of 4 gives him the memory address 4 spaces in front, so that means he is assingning the letter 'c' to the memory address rather than at the value stored at that address. 我的问题是,p1是一个指针,所以它是一个内存地址,偏移量4使他的内存地址在前面有4个空格,这意味着他将字母“ c”设置为内存地址,而不是值存储在该地址。 Shouldnt it be: 不应该是:

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

basically, how come *(p1 + 4) needs dereferencing but p1[4] does not? 基本上,*(p1 + 4)为什么需要解引用,而p1 [4]不需要解引用?

I tried to understand this and the only thing that could make sense to me was if the square brackets act as an asterisk to dereference the pointer. 我试图理解这一点,对我来说唯一有意义的是,如果方括号充当取消引用指针的星号。 Is this correct or is there another reason why p1[4] does not need to be dereferenced? 这是正确的还是有其他原因为什么不需要取消引用p1 [4]?

then he creates a pointer to the array: 然后他创建一个指向数组的指针:

 *p1 = myString; 

Assuming, by this, you actually mean that p1 is declared and initialised using; 假设,这实际上意味着您使用p1声明并初始化了p1

char *p1 = myString;

then your interpretation is wrong. 那么你的解释是错误的。 p1 is a pointer to a char not a pointer to an array. p1是指向char的指针,而不是指向数组的指针。

In this definition, myString is the (previously declared in your question) name of an array of char . 在此定义中, myStringchar数组的名称(先前在您的问题中声明)。 In the initialisation 在初始化中

char *p1 = myString;

the name myString is converted to a pointer. 名称myString将转换为指针。 That pointer will have the value &myString[0] (ie the address of the first character in myString ). 该指针将具有值&myString[0] (即myString中第一个字符的地址)。 That is the value that p1 will receive. 这就是p1将接收的值。

The statement 该声明

 p1[4] = 'c';

will then set the fifth character (since indexing is zero based) of myString to be 'c' . 然后将myString的第五个字符(因为索引从零开始)设置为'c' The result is therefore changing myString[4] to the value 'c' . 因此,结果是将myString[4]更改为值'c' This means that (the first 11 characters of) myString will be "Hellc there" . 这意味着myString (的前11个字符)将为"Hellc there"

Assuming the above, the expression *(p1[4])='c' will not compile, since (p1[4]) is of type char , and cannot be dereferenced using the * operator. 假设以上情况,由于(p1[4])的类型为char ,因此无法使用*(p1[4])='c'进行编译,并且无法使用*运算符对其进行引用。

Semantically, in an expression p1[4] is equivalent to *(p1 + 4) . 语义上,表达式p1[4]等于*(p1 + 4) Since p1 is initialised to be equal to &myString[0] , p1[4] is ALSO equivalent to both myString[4] and to *(myString + 4) . 由于p1初始化为等于&myString[0] ,因此p1[4]也等同于myString[4]*(myString + 4)

Note: If *(p1[4])='c' was valid in your code, then p1[4] = 'c' would not be valid, which suggests my assumption about the declaration and initialisation of p1 is correct - despite the fact you have omitted such information. 注意:如果*(p1[4])='c'在您的代码中有效,则p1[4] = 'c'将无效,这表明我对p1的声明和初始化的假设是正确的-尽管实际上您已经省略了此类信息。

p1 + 4 would be the memory address 4 places beyond. p1 + 4将是超出4位的内存地址。

The expression p1[4] (exactly equivalent to *(p1+4) ) is called an lvalue expression. 表达式p1[4] (完全等于*(p1+4) )称为左值表达式。 We say that an lvalue expression designates a memory location. 我们说一个左值表达式指定一个存储位置。 Or in other words, the lvalue expression is synonymous with the memory location itself. 换句话说,左值表达式与存储位置本身同义。 You can always use the & address-of operator on an lvalue expression, and that gives you a pointer to the memory location. 您可以始终在左值表达式上使用& address-of运算符,这为您提供了指向内存位置的指针。

The lvalue expression will go on to be used in one of three possible ways: 左值表达式将继续以三种可能的方式之一使用:

  1. Store a value in the designated memory location, or 将值存储在指定的存储位置,或者
  2. Retrieve a value from the designated memory location, or 从指定的存储位置检索一个值,或者
  3. Neither of those. 都不是。

There is no special syntax to distinguish between these three cases; 没有区分这三种情况的特殊语法。 rather it depends on the larger expression of which the lvalue expression is a part of. 相反,它取决于左值表达式所属的较大表达式。 For example, applying the & operator is case 3; 例如,应用&运算符是第3种情况; appearing on the left-hand side of the assignment operator = is case 1. Most other usages fall under case 2. 出现在赋值运算符=左侧的是案例1。大多数其他用法都属于案例2。

p1[4] is treated as *(p1 + 4) which is "value at an offset of 4 from p1". p1[4]被视为*(p1 + 4) ,即“相对于p1的偏移量为4的值”。

Also when you declare a char array: 同样,当您声明一个char数组时:

myString[80]

myString is a pointer to the array (It points to the first element). myString是指向数组的指针(它指向第一个元素)。 So when you do myString[4] it is also treated as *(myString + 4) 因此,当您执行myString[4]它也被视为*(myString + 4)

Writing *(p1[4]) would mean *(*(p1 + 4)) *(p1[4])意味着*(*(p1 + 4))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM