【问题标题】:Why do I get "Incompatible types when assigning" error?为什么我会收到“分配时不兼容的类型”错误?
【发布时间】:2014-07-18 06:03:32
【问题描述】:

我的 C 代码似乎有类似的指针分配,但在编译时表现出不同的行为。

我的结构声明和定义如下,

typedef struct {
    int a;
    char b[20];
}
TestStruct;
TestStruct t1;

为什么下面的代码给出“错误:从‘char *’类型分配给‘char[20]’类型时不兼容的类型”

t1.b = "Hello World";

但是下面的代码编译成功,

char *charPtr = t1.b;
charPtr = "Hello World";

注意:我使用的是 GCC 编译器 v4.6.3

【问题讨论】:

  • 指针就像一个人的名字;它指向的就像那个名字的人。想象一下,试图让一个人在要求姓名的表格上排队,或者把一个人的名字放在椅子上而不是这个人自己......

标签: c


【解决方案1】:

这些字符串不能分配给 C 中的数组,除非作为初始化的一部分。
执行此类操作的正确方法是通过<string.h> 标准标头的函数strcpy()

    strcpy(t1.b, "Hello world");  

数组t1.b 不是指向char 的指针。
实际上,它有 20 个 char 类型元素的数组
在表达式中,数组通常衰减为 指向 char 的指针

然而,数组在内存中有一个固定的地址。它不是左值,它的地址不能被赋值改变。

相反的赋值有效:

  charPtr = "Hello World";  

字符串“Hello world”的地址分配给charPtr
但是,您的句子没有预期的效果:

   char *charPtr = t1.b;
   charPtr = "Hello World";

效果是charPtr变得等于t1.b的地址。
然后,这个值在第二句中被丢弃,代之以数组“Hello world”的地址。

更多细节:小心处理字符串。像“Hello world”这样的字符串文字是(通常)存储在只读存储器中的数组。如果你尝试修改它,你会得到意想不到的结果。

尤其是在赋值 charPtr = "Hello world" 时会发生这种情况。
字符串可以读取,但不能更改。

要更改或操作字符串,必须将其复制(使用strcpy())到数组或分配的内存部分。

【讨论】:

  • 当你说“像“Hello world”这样的字符串文字是一个存储在只读内存中(通常)的数组”......这个内存使用量是否计入分配的总内存并且确实这段记忆在我们不知情的情况下被覆盖了?
  • 程序运行时,字符串会在那里,没有任何变化。别担心。但是,如果您尝试访问那部分内存并尝试修改它们的字节,则很可能会发生错误。喜欢"Hello"[3] = 'x' 的东西可能会带来执行错误或非常规和微妙的行为。这取决于编译器或环境。
【解决方案2】:

您不能直接将字符串文字分配给char 数组。使用strcpy()strlcpy()

在第二个示例中,数组衰减为一个指针,然后您更改该指针。请注意,在此示例中,t1.b 保持不变。

【讨论】:

  • 但我在想 't1.b' 和 'charPtr' 是指向同一个位置的指针。但是这两个任务都有不同的结果。如果我错了,请纠正我
  • @user3665376:这里有两个误解。首先,数组和指针不是一回事:c-faq.com/aryptr/aryptr2.html。其次,即使你有两个指针并改变一个,这不会改变另一个。
【解决方案3】:

当你定义时:

typedef 结构 { 诠释一个; 字符 b[20]; }TestStruct;

b 是一个指向 char 的 常量指针。因此 t1.b = "Hello World";是一个编译错误,因为它改变了 t1.b 的值

解决方案:

1) 使用 strcpy:

    strcpy(t1.b, "Hello World");

2) 棘手的类型转换方式

    char** pb = (char**)&t1.b;
    *pb = "Hello World";

虽然这两种方法的目的相同(将 t1.b 设置为“Hello World”字符串),但其基本思想却大不相同。

【讨论】:

    【解决方案4】:

    您不能将const char* 分配给char[],因为它违反了恒常性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-07
      • 1970-01-01
      • 2017-01-04
      • 2017-11-30
      • 2014-04-23
      • 2022-06-29
      • 2015-06-19
      • 2019-12-20
      相关资源
      最近更新 更多