我希望能够像这样做:
typedef struct
{
char* c_str;
} string;
string s = "hello";
有什么办法可以做到吗?
我知道可以做到这一点:
typedef struct
{
char* c_str;
} string;
string s = { "hello" };
但是当只有一个成员变量时,我不喜欢使用大括号。
我希望能够像这样做:
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 string s
等价于char* const s
。一种解决方法是为常量字符串定义另一种类型:
typedef char* string;
typedef const char* const_string;
对于原始结构体,同样适用这个问题。(C++也有同样的“问题”,这就是为什么它在其容器类型中使用iterator
和const_iterator
的原因。)
对于指针类型的typedef的优点是可以缩短类型的长度。
string s1, s2, s3;
而不是
char *s1, *s2, *s3;
在 C 中无法实现,但如果您添加一个接受一个适当参数的构造函数,则可以在 C++ 中完成。编译器将完成其余工作。如果想要避免隐式转换行为,可以将构造函数标记为显式(explicit)。
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;
}
struct
或union
来实现。第6.7.9节的第16段规定:不确定这是否符合C标准,并且由于微软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}
如果你希望在某些情况下对特定类型的char *
进行编译时参数检查,那么初始化列表似乎确实是最好的方法。
当你像下面这样使用初始化列表在定义结构体变量的同时初始化多个结构体成员时,就会让人感到非常棒。
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
}
typedef
定义指针时,众所周知的一个问题是,const
被应用于指针而不是指向的数据。换句话说,const string s
将等同于char* const s
而不是你通常期望的const char* s
。 - barak manostypedef
的另一个问题是它创建的是类型的别名而不是新类型。结果是编译器进行的类型检查与 C++ 中所期望的不同。因此,对char *
进行typedef
将与任何其他char *
一样,就编译器而言。如果问题是通过使用struct
提供更具体的类型检查方式,则使用typedef
将无法提供编译器类型检查。 - Richard Chambers