繁体   English   中英

我可以strupr工作但strcpy无法工作

[英]How is it that I can strupr work but strcpy does not

这是我的代码。

int main()
{
struct emp
{
    char *n;
    int age;
};
struct emp e1 = {"Dravid", 23};
struct emp e2 = e1;
strupr(e2.n);
printf("%s\n", e1.n);
return 0;
}

问题1:根据网站的答案是大写的“ DRAVID”。 怎么了,e2和e1一样吗? 即如果我这样做,那么e2.age ++也会在e1中反映出来吗?

问题2:如果将strupr更改为strcpy,则会出现段错误? 为什么? 即如果我将其更改为strcpy(e2.n,"hoho");

构建两个emp ,这就是您的内存:

e1.age  = 23
e1.name = 0x12345678 (Which is a pointer in memory to "Dravid")
e2.age  = 23
e2.name = 0x12345678 (Which is a pointer in memory to "Dravid")

现在记下您要尝试执行的操作。

  1. 调用strupr(e1.name)是未定义的行为,因为不允许您修改字符串文字。
  2. 调用strcpy(e1.name, e2.name)也是未定义的行为,因为strcpy要求传递给它的两个指针引用不同的内存。 另外,它的UB是因为您不能修改字符串文字。
  3. 调用strcpy(e1.name, "hiho")也是未定义的行为,因为您不能修改字符串文字。

1)分配结构会进行成员复制。 由于n是指针,因此将复制指针地址,使其指向相同的字符串。

2) strcpy需要两个参数。 记住e2.n是一个指针。 调用strcpy时,必须为该指针分配足够的空间以容纳新字符串的内容。 您最好使用strncpy()

int maxlen = 20;
e2.n = malloc(maxlen);
strncpy(e2.n, "Any length string here", maxlen - 1) /* only copies 19 bytes + terminating null */

将一个结构复制到另一个结构时,将复制该结构中的所有值。 对于年龄,您只需复制该值,即可更改它,它们将有所不同。

对于n,您正在复制字符串的地址,因此,当您更改一个字符串时,也会更改另一个字符串。

而且,正如H2CO3所指出的那样,您无法修改使用strcpy时要尝试执行的字符串文字。

Q1。 char * n存储要复制的地址,因此,如果更改该值,则两者都会反映出来。

Q2。 strcpy()需要2个参数,您能否显示代码。

与Java不同,C使用不同的内存区域存储不同的变量。 因此,当您将一个结构分配给另一个结构时,它基本上是将一个区域的浅表副本复制到另一个区域。 我所说的浅表复制是指没有遵循任何指针来对其进行克隆,因此任何指针都将指向同一位置。 它只是一个存储区域到另一个存储区域的副本。

要说struct emp e2 = e1; 和说memcpy (&e2, &e1, sizeof(struct emp));是一样的东西memcpy (&e2, &e1, sizeof(struct emp));

反过来这意味着,如果将一个结构分配给另一个结构变量,然后修改另一个结构变量中的数据,则第一个结构变量不会被修改。

因此,在C语言中,每个变量都是一个不同的内存位置,就像Java和其他一些语言一样,您在其中使用变量引用,并且变量名称只是变量引用的容器(除了内置原语(如int))。

您的代码可能存在一些问题,因为您使用的是常量字符串。 像使用strupr()那样修改常量字符串是不好的,因为您不知道内存是如何分配的或在哪里分配的。 因此,通过执行strupr(),您基本上会很幸运。

有关深层副本和浅层副本之间的区别,请参见此内容。

在调用strupr之后,它们应该不相同(但是修改字符串文字既不安全也不适当)。 不,对e2的更改将不会反映在e1因为赋值将按值复制对象。

至于将strupr调用更改为strcpy,strcpy需要两个参数,因此仅对其进行更改将导致编译错误。 如果将e1.n添加为第二个参数,它将崩溃,因为e2.n尚未初始化为指向任何内存。

暂无
暂无

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

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