繁体   English   中英

C结构作为数据类型

[英]C structure as a data type

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

typedef struct
{
    char* c_str;

} string;

string s = "hello";

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

我知道可以这样做:

typedef struct
{
    char* c_str;

} string;

string s = { "hello" };

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

您可以使用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;

在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;

}

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

不可以。不能用structunion来做。 6.7.9节第16段指出:

具有聚合或联合类型的对象的初始化程序应是元素或命名成员的初始化程序括号括起来的列表

如本答案所述,还有另一种对不同数据类型执行相同操作的方法。

由于Microsoft Visual Studio在解释该标准时有些松懈的声誉,因此不确定它是否真正符合C标准,但是在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
}

暂无
暂无

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

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