lvalue需要作为递增操作数

ant*_*009 24 c pointers

gcc 4.4.4

我究竟做错了什么?

char x[10];
char y[] = "Hello";
while(y != NULL)
    *x++ = *y++;
Run Code Online (Sandbox Code Playgroud)

非常感谢任何建议.

nai*_*ore 29

x++是简短的形式x = x + 1.但是,x这是一个数组,您无法修改数组的地址.您的变量y也是如此.

您可以声明一个整数i并递增该i数组,然后访问数组的第th个索引,而不是尝试递增数组.

char x[10], y[5] = "Hello";
int i = 0;
while (y[i] != 0)
{
    x[i] = *y[i];
    i++;
}
x[i] = 0;
Run Code Online (Sandbox Code Playgroud)

  • 为什么要在同一个代码中混合使用`*(x + i)`和`x [i]`表单? (5认同)

AnT*_*AnT 23

很可能你成了一个流行的误解"数组是一个指针"的受害者,即当你定义一个数组时你实际得到的是一个普通指针指向某个地方分配的某个内存块.在您的代码中,您尝试增加该指针.

代码不"有效",因为实际上数组不是指针.数组是数组.数组不能递增.在C语言中没有"增加数组"这样的操作.实际上,C中的数组本身是不可修改的左值.C中没有可以修改数组本身的操作(只有单个元素可以修改).

如果你想使用"滑动指针"技术遍历你的数组(你正在尝试这样做),你需要显式创建指针并使它们指向数组的起始元素

char *px = x;
char *py = y;
Run Code Online (Sandbox Code Playgroud)

之后,您可以根据需要增加这些指针.

  • 在"现实"中,数组**是**指针.确实,像`char myString []`这样的堆栈分配数组在不能修改指针地址的意义上是不可变的.但这并没有改变它们仍然是指针的事实,即位于堆栈中的一块内存的开头.因此,当您说"数组不是指针"时,您直接与理解C所必需的基本实现细节相矛盾. (3认同)
  • 好吧,那么`printf("%p",myString)`print?哦,对,一个内存地址.原因p是指针.因为它们是作为指针实现的,因为当您将数组发送到需要指针的函数时,不会引发类型错误.即使在带有`-Wall -pedantic`的C++编译器中也是如此.为什么有人会相信它是一个指针?也许是因为它.也许是因为`*myString`取消引用地址并返回指针指向的值.指针是矩形,数组是正方形.所有数组都是指针,但并非所有指针都是数组.它们不是互相排斥的. (3认同)
  • `array [n]`是`*(指针+ n)`的语法糖.您可能会发现它令人惊讶,在您的妄想中,一切都是高级别的,机器代码不存在幻想世界,`n [array]`将返回完全相同的东西并且不会产生C或C++编译器的单个错误或警告用`-Wall -pedantic`运行.在实践中看到的所有可观察的证据都指向数组是指针的语法糖.单个矛盾,即数组的地址不能在其定义的相同范围内修改,并不意味着它无论如何只能传递给另一个函数. (3认同)
  • @Braden Best:不。您的“printf”正确打印内存地址只是因为在这种情况下的C语言数组“myString”立即受到所谓的**数组到指针的转换**(又名“数组类型衰减”) 。该转换的临时结果(实际上是一个指针)被发送到“printf”而不是数组。你们所有的小实验也是如此,都已经被打死了,我之前说过了。我给您的常见问题解答链接解释了所有这些。 (3认同)
  • @Braden Best:错了。数组不是指针。这确实是一个基本细节,理解它是理解 C 所必需的。这个问题已经被解释得要死了(http://c-faq.com/aryptr/index.html),而且很少见有人会这样做。 2016 年的今天,我们仍在为这个概念而挣扎。Dennis Ritchie 决定放弃实现数组的指针,这是该语言发展的关键步骤之一。你今天还不断重申“数组就是指针”这种废话吗? (2认同)
  • 那么,您是否试图声称“int a;”也是一个指针?您是否试图声称每个“struct”对象都是一个指针?基本上,这个逻辑会让我们得出这样的结论:C 中的每个对象和每个函数都是“真正的指针”。抱歉,虽然这在汇编语言术语中可能成立,但这与 C 无关。在 C 语言中,内存中的对象称为**左值**。**Lvalue** 是您所讨论内容的正确 C 术语。C中的“左值”和“指针”是两个完全不同的概念。不要混合它们。并且数组不是 C 中的指针。 (2认同)

小智 7

C中的数组确实是指针,但是常量指针,这意味着在声明之后它们的值不能被改变.

int arr[] = {1, 2, 3};
// arr is declared as const pointer.
Run Code Online (Sandbox Code Playgroud)

(arr + 1)是可能但arr++不可能,因为arr它不能存储另一个地址,因为它是常量.


Jac*_*cob 5

char x[10];
char y[] = "Hello";
char *p_x = &x[0];
char *p_y = &y[0];
while(*p_y != '\0') *p_x++ = *p_y++;
Run Code Online (Sandbox Code Playgroud)

由于您无法修改数组地址(由代码完成x++y++在代码中完成)并且您可以修改指针地址,因此我将数组的地址复制到单独的指针中然后递增它们.

如果你愿意,我相信你可以减少乐谱,但我希望你明白这一点.


CB *_*ley 5

xy是数组,而不是指针。

在大多数表达式上下文中,它们会衰减为指针,例如增量表达式,但它们会衰减为右值,而不是左值,并且您只能将增量运算符应用于左值。