C结构作为数据类型

时间:2015-04-25 15:32:37

标签: c

我希望能够做到这样的事情:

typedef struct
{
    char* c_str;

} string;

string s = "hello";

有可能以任何方式这样做吗?

我知道可以这样做:

typedef struct
{
    char* c_str;

} string;

string s = { "hello" };

但是当我只有一个成员变量时,我不喜欢花括号。

4 个答案:

答案 0 :(得分:31)

您可以使用typedef代替struct

typedef char* string;
string s = "hello";

但是const string会使指针成为const,而不是指向数据。因此const string s相当于char* const s。解决方案可能是为const字符串定义一个附加类型:

typedef char* string;
typedef const char* const_string;

对于原始结构,同样如此。 (C ++有相同的“问题”,这就是它在容器类型中有iteratorconst_iterator的原因。)

指针类型的typedef的一个优点是可以键入

string s1, s2, s3;

而不是

char *s1, *s2, *s3;

答案 1 :(得分:14)

在C中,它是不可能的,但如果添加带有一个适当参数的构造函数,则可以在C ++中完成。编译器将完成剩下的工作。如果要避免此隐式转换行为,可以将构造函数标记为显式。

在C ++中:

struct string {

    char * m_c_str;

    /* explicit */ string(char* c_str) : m_c_str(c_str) { }
};

int main(int argc, char * argv[]) {

    string s = "hello";

    return 0;

}

答案 2 :(得分:4)

  

有可能以任何方式做到这一点吗?

没有。使用structunion无法执行此操作。第6.7.9节第16段指出

  

[...]具有聚合或联合类型的对象的初始值设定项应为元素或命名成员的括号关闭的初始值设定项列表

如本answer中所述,还有另一种方法可以使用不同的数据类型。

答案 3 :(得分:3)

不确定这是否真的是规范并且符合C标准,因为Microsoft Visual Studio在解释标准时有一点点松散的声誉,但是这是一种在Visual Studio 2005的调试器中查看时编译和工作的方法

虽然如果你不喜欢花括号初始化器,你可能也不会关心宏。

typedef struct {
    char *c_str;
} String;

// following macro assigns the string to the struct member and uses the
// comma operator to make the statement return the original struct variable.
#define xString(x, y) ((x).c_str = (y), (x))

void jjj (void)
{
    String b = xString(b,"hello");

}

我能够一次定义多个变量,因此同一行上的多个变量定义编译如下:

String b = xString(b,"hello"), c = xString(c,"Jello");

可能你希望有一个宏可以用一种函数式语言查看构造来完成整个语句,尽管每个语句只能有一个,所以在同一行上有多个需要用分号分隔成单独的定义语句。

#define xString(x,y) String x = (x.c_str = (y), x)

它将用作

void jjj (void)
{
    xString(myStruct, "hello");
    int  j = 2;

    //  .. do stuff
}

或者您可以使用

#define xString(x,y) String x = {y}
如果由于某种原因希望struct允许对特定类型的char *进行编译时参数检查,

初始化列表确实似乎是最好的方法。

当你在定义struct变量时初始化多个struct成员时,你会做类似的事情。

typedef struct {
    int len;
    char *c_str;
} String2;

#define yString(x,y) x = (x.c_str = (y), x.len = strlen(y), x)

void jjj (void)
{

    String2 b2 = yString(b2,"Hello");
    int  j = 2;

    //  .. do stuff
}

好奇我尝试了另外一种看起来如下的变体。这确实远离了具体问题,更多的是在兔子洞中遵循这种方法的可能性。使用具有不同宏的相同struct,允许您指定struct成员以及值初始化。

typedef struct {
    int len;
    char *c_str;
} String2;

#define zString(x,y,a,b) x=(x.c_str=(y),x.a=(b),x)

void jjj (void)
{
    String2 b3 = zString(b3,"Hello",len,72);

    //  ... do stuff
}