为啥我不能像往常一样初始化 typedef struct string 或 char?

Posted

技术标签:

【中文标题】为啥我不能像往常一样初始化 typedef struct string 或 char?【英文标题】:Why can't I initialize a typedef struct string or char as normally?为什么我不能像往常一样初始化 typedef struct string 或 char? 【发布时间】:2019-07-13 09:31:33 【问题描述】:

我是编程和 C++ 的初学者。

在 Linux 上编程,我正在创建一个 typedef 结构如下:

typedef struct 

    char id[10];
    string name[20];    

Employee;

通常,当不使用 struct 时,我会初始化 string char:

char id[10]="ID02093";
string name="Joe";

那么,为什么我不能初始化 Employee 结构的 char id 和 string name 如下?:

Employee salesManager;
salesManager.id="ID02093";
salesManager.name="Joe";

我从 g++ 编译器得到这个错误:

“将‘const char [8]’分配给‘char [9]’时的类型不兼容 salesManager.id="ID02093";" 'const 分配中的不兼容类型 char [4]' 到'std::__cxx11::string [20] aka std::__cxx11::basic_string [20]' salesManager.name="Joe";

从 typedef struct 声明中初始化 typedef struct 元素的 string 和 char 的正确方法是什么?

【问题讨论】:

提示:初始化只发生在声明变量的那一行。之后就是分配。 这看起来更像 C 而不是(现代)C++。 char 是单个字符。你可能需要更多的东西来识别员工,所以数组更好但是我还是会为两者都使用 std::string。 @PlàcidMasvidal: "char name[10] 是一个字符串" -- 不,不是。这是一个数组。它可能包含字符串。 C 中的 string 定义为“由第一个空字符终止并包括第一个空字符的连续字符序列”。 您的问题被标记为 C,但您正在使用 g++(C++ 编译器)进行编译,并且您接受了使用 C++ 特定类型 std::string 的答案。它们是两种不同的语言。在 C++ 中,typedef 是多余的。在 C 语言中,它也大多是多余的,但如果定义 struct Employee ... ,则必须将类型称为 struct Employee 而不仅仅是 Employee 【参考方案1】:

初始化和赋值是两个不同(但相似)的东西。

您可以通过在声明/定义数组时为其提供值来初始化数组。

您不能分配给数组。

您可以使用memcpystrcpy 将值复制到数组中:

char name[20];
strcpy(name, "Test";

但出于您的目的,您可以将数组初始化为结构初始化的一部分:

typedef struct 
    char id[10];          
    char name[20];
 Employee;
Employee salesManager = 
    "A12345678",
    "Test"
;
/* OR */
Employee salesManager = 
    .id = "A12345678",
    .name = "Test"
;  

由于您询问的是 C++ 而不是 C,因此使用 std::string 而不是原始字符数组可能会更好。 std::string 更加灵活:您可以将值(包括字符串文字)分配给 std::string 对象。

【讨论】:

我不知道如何使用 std::string 我是初学者,在课堂上我们还没有研究它。这种情况下怎么用? @PlàcidMasvidal:如何使用std::string 是一个太大的话题,无法在评论中解决。我想你很快就会在你的课上得到它。如果你想早点开始,cppreference.com 是一个很好的参考:en.cppreference.com/w/cpp/string/basic_string【参考方案2】:

我认为你应该在这两种情况下都使用字符串,并使用 OOP 而不是 typedef。但是试试下面的代码,应该可以正常工作:

#include <iostream>

using namespace std;

typedef struct 

    string id;
    string name;    

 Employee;


int main() 
    Employee salesManager;
    salesManager.id = "A12345678";
    salesManager.name = "Test";

    cout << "Id: " << salesManager.id << endl;
    cout << "Name: " << salesManager.name << endl;

    return 0;

【讨论】:

我想对此投赞成票,但其余的 c-isms 需要删除。您也可以在声明 salesManager 时初始化这两个元素,而不是稍后再分配。 There's no need for typedef struct ... Employee;,当 struct Employee ... ; 会很好。 是的,我同意。我只是按照他的逻辑这样做。 "使用 OOP 而不是 typedef" 你在混合东西。 typedef 在那个地方只是不必要的,与 OOP 或没有 OOP 无关【参考方案3】:

您不能分配给char 的数组

考虑到这一行:

salesManager.id="ID02093";

您可以使用字符串字面量来初始化char 的数组,以方便继承自 C 的 C++ 语法。但是,您不能对数组使用赋值。这就是您收到此错误的原因:

incompatible types in assignment of ‘const char [8]’ to ‘char [9]’ salesManager.id="ID02093";

相反,您必须将数据复制到数组中。

您不能分配给string 的数组

考虑到这一行

salesManager.name="Joe";

失败的原因是你已经将name 声明为一个数组。

typedef struct 

    char id[10];
    string name[20];    

Employee;

这解释了您收到此错误的原因:

incompatible types in assignment of ‘const char [4]’ to ‘std::__cxx11::string [20] aka std::__cxx11::basic_string [20]’ salesManager.name="Joe";

您可能不是有意将 name 声明为一个数组。

避免使用匿名类

为匿名类类型指定的typedef 名称与类名称的语义略有不同。由于差异很棘手,因此如果匿名类不包含在类本身中,最好避免使用它。

【讨论】:

以上是关于为啥我不能像往常一样初始化 typedef struct string 或 char?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能像行一样简单地获得一维数组?

为啥我不能让球跳起来?它像火箭一样飞起来

为啥我不能像使用列表一样过滤 IQueryable?

为啥我不能像传递其他变量一样将函数从 Express.js 传递给 EJS?

为啥结构在 Swift 中没有像类一样的反初始化器?

为啥朴素贝叶斯不能像逻辑回归一样在 Spark MLlib 管道中工作?