-1

这是我的代码。

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 会出现 seg 错误?为什么?即,如果我将其更改为strcpy(e2.n,"hoho");.

4

6 回答 6

3

构建两个emps 后,这就是您在内存中的内容:

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")也是未定义的行为,因为您不能修改字符串文字。
于 2012-10-24T18:24:00.940 回答
1

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 */
于 2012-10-24T18:21:09.773 回答
1

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

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

而且,正如 H2CO3 指出的那样,您不能修改字符串文字,这是您在使用 strcpy 时尝试做的事情。

于 2012-10-24T18:21:49.787 回答
1

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

Q2。strcpy() 需要 2 个参数,你能显示你的代码吗?

于 2012-10-24T18:25:36.230 回答
0

与 Java 不同,C 对不同的变量使用不同的内存区域。因此,当您将一个结构分配给另一个结构时,它基本上是一个区域到另一个区域的浅拷贝。通过浅拷贝,我的意思是任何指针都不会被复制来克隆,因此任何指针都将指向同一个地方。它只是一个内存区域到另一个内存区域的副本。

说和说struct emp e2 = e1;是一回事memcpy (&e2, &e1, sizeof(struct emp));

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

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

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

看到这个关于深拷贝和浅拷贝之间的区别

于 2012-10-24T18:25:46.580 回答
-1

在调用 strupr 之后它们不应该是相同的(但无论如何修改字符串文字是不安全或不正确的)。不,更改e2不会反映,e1因为分配将按值复制对象。

至于将 strupr 调用改成 strcpy,strcpy 有两个参数,所以只改会导致编译错误。如果添加e1.n为第二个参数,它将崩溃,因为e2.n尚未初始化为指向任何内存。

于 2012-10-24T18:23:17.977 回答