C:试图将指针值复制到另一个指针中,得到可修改的左值错误
Posted
技术标签:
【中文标题】C:试图将指针值复制到另一个指针中,得到可修改的左值错误【英文标题】:C: Attempting to copy pointer values into another pointer, getting modifiable lvalue error 【发布时间】:2019-11-20 01:36:50 【问题描述】:我正在学习 C 并且遇到困难。基本上我声明了 2 个数组,我想通过使用指针将一个数组的所有 char 值复制到另一个数组中。我正在利用数组名称是指向其第一个元素的指针这一事实。有人可以帮忙看看吗?谢谢。
#include<stdio.h>
#include<string.h>
char *mystrcopy(char*p, char*q); //function prototype
int main(void)
char s1[20] = "Hello\n";
char s2[20] = "Bye\n";
puts(s1); //print Hello
mystrcopy(s1, s2); //call function using pointers s1 and s2
puts(s1); //I want this to print Bye after function has run
system("pause"); //"press any key to continue...."
return 0;
char *mystrcopy(char*s1, char*s2)
int i;
for (i = 0; s1 + i; i++) //for loop continues as long as s1+1 not 0
s1 + i = s2 + i; //error says s1 is not a modifiable lvalue
return s1; //I know this could be a void function but I choose not to
我认为这很好,因为 (s1 + i) 是指向数组 s1 中的第 i 个元素的指针,并将其替换为 s2 中的第 i 个元素。
我尝试过使用
*(s1+i) = *(s2+i)
相反,将 s2 的地址复制到 s1 中,但我得到了同样的错误。
编辑:
上面的for循环中的代码确实有效
*(s1+i) = *(s2+i)
我认为这不起作用,因为循环一直在进行。不过,感谢大家回答我关于可修改 l 值的问题。
【问题讨论】:
赋值的左边必须是一个变量。尝试使用数组表示法来访问您想要的字符,而不是尝试指针运算。 "s1+i" 将评估为真,直到此表达式评估为 0。一旦您修复此编译错误,除非您也修复此错误,否则在现代 64 位平台上,此for
循环将平均执行 9223372036854775808 次(根据我的计算),这将需要……一点时间。幸运的是,它会比这更快地崩溃。你需要准确地解释你期望这个函数做什么,以便任何人也能帮助你解决这个问题。
可能你忘了修复循环条件
罗伯特-谢谢你的评论。我已经使用数组表示法做了这个练习。我只是想用指针挑战自己。
山姆-谢谢你的评论。哇,这么大的数字。你在这个循环上是正确的。我想通过 s1 循环它,它只有 20 个元素,当它到达数组末尾的换行符时循环退出,但我意识到这不是零。谢谢你。另外,我在代码右侧留下的 cmets 中解释了我希望代码做什么,最值得注意的是: puts(s1); //我希望在函数运行后打印 Bye
【参考方案1】:
这样的事情会让你开始。请注意,我们必须取消引用副本中的 char*。这假定字符串长度固定,因此不需要使用 std 库中的 malloc 或 strlen 函数。不理想,但您可以开始使用。
#include<stdio.h>
#include<string.h>
char *mystrcopy(char* p, char* q); //function prototype
#define LENGTH 20
int main(void)
char s1[LENGTH] = "Hello\n";
char s2[LENGTH] = "Bye\n";
puts(s1); //print Hello
mystrcopy(s1, s2);
puts(s1); //I want this to print Bye after function has run
// system("pause"); //"press any key to continue...."
return 0;
char *mystrcopy(char* s1, char* s2)
int i;
for (i = 0; i < LENGTH; i++, ++s1, ++s2) //for loop continues as long as s1+1 not 0
*s1 = *s2; //error says s1 is not a modifiable lvalue
return s1; //I know this could be a void function but I choose not to
【讨论】:
你是上帝。非常感谢。这绝对有效。【参考方案2】:由于s1
是一个指针,那么s1 + 1
也产生一个指针(只是一个地址已被移动的临时指针。
如果我们放置一些中间变量,那么您的循环实际上将等效于:
for (i = 0; s1 + i; i++)
char* t1 = s1 + i;
char* t2 = s2 + i;
t1 = t2;
需要注意的一个主要因素是它不会改变指向的数据中的任何内容。它只是将一个指针的值分配给另一个。
现在回顾s1 + 1 = anything
时,它试图将某些内容分配给临时指针(而不是临时指针指向的内容)。所以编译器抱怨作为一种保障,因为试图分配给一个临时的总是一个错误。
所以知道你真正想要做什么(同时注意s1 + 1
的循环条件不是读取指向的值,代码需要调整。对于这种情况,类似数组的语法允许使用指针比尝试增加指针本身要方便得多。因此你最终会得到类似的东西:
for (i = 0; s1[i]; i++)
s1[i] = s2[i];
作为额外考虑,您的逻辑从s2
复制到s1
,但循环以s1
为条件。那么如果s1
中的初始数据比s2
中的数据短,会发生什么?也许你的循环条件应该是s2
。
如果指向s1
和s2
的数组大小不同,未来的考虑是什么。会出现什么样的问题?也许您的函数可以采用一个额外的参数来指定s1
的最大大小。
最后一个考虑因素是,std::string
比使用 char
数组自己做更容易、更安全。
【讨论】:
哇,感谢您的周到和耐心的评论。你真好!我得到的最大收获是:需要注意的一个主要因素是它不会改变所指向的数据中的任何内容。它只是将一个指针的值分配给另一个指针。 这有助于我澄清这个问题。因此,即使我正在更改指针的值,如果我返回并打印 s1 数组本身,如果我根本没有该函数,它也不会做任何不同的事情。但是 temporary 指针是什么意思?怎么是暂时的?非常感谢。 @miltongoldman 假设我们有一行代码a = b + c;
编译器首先计算b + c
,然后以临时方式挂起结果。接下来,它将该临时值分配给a
。因此,如果我们有 x + y = z;
编译器首先弄清楚 x + y
是什么,将其作为临时的,然后......好吧,问题是代码行没有将 z
分配给任何一个x
或 y
而是临时组合它们 - 这不是开发人员一开始就应该打算做的事情。以上是关于C:试图将指针值复制到另一个指针中,得到可修改的左值错误的主要内容,如果未能解决你的问题,请参考以下文章
C++的结构体指针中出错:表达式必须是可修改的左值_最后发现解决方法很简单