use*_*514 763 c struct typedef
我是C编程的初学者,但我想知道typedef在定义结构时使用与使用结构之间有什么区别typedef.在我看来,实际上没有区别,他们实现了同样的目标.
struct myStruct{
int one;
int two;
};
Run Code Online (Sandbox Code Playgroud)
与
typedef struct{
int one;
int two;
}myStruct;
Run Code Online (Sandbox Code Playgroud)
Dav*_*eas 959
常见的习语是同时使用:
typedef struct X {
int x;
} X;
Run Code Online (Sandbox Code Playgroud)
它们是不同的定义.为了使讨论更清楚,我将分开句子:
struct S {
int x;
};
typedef struct S S;
Run Code Online (Sandbox Code Playgroud)
在第一行中,您将S在结构名称空间中定义标识符(而不是在C++意义上).您可以使用它并通过将参数的类型定义为struct S:定义新定义类型的变量或函数参数:
void f( struct S argument ); // struct is required here
Run Code Online (Sandbox Code Playgroud)
第二行在S全局名称空间中添加了一个类型别名,因此您只需编写:
void f( S argument ); // struct keyword no longer needed
Run Code Online (Sandbox Code Playgroud)
请注意,由于两个标识符名称空间不同,S因此在结构和全局空间中定义它们都不是错误,因为它不重新定义相同的标识符,而是在不同的位置创建不同的标识符.
为了使差异更清楚:
typedef struct S {
int x;
} T;
void S() { } // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
Run Code Online (Sandbox Code Playgroud)
您可以定义具有相同结构名称的函数,因为标识符保存在不同的空格中,但是您无法定义与typedef这些标识符碰撞时具有相同名称的函数.
在C++中,它略有不同,因为定位符号的规则已经巧妙地改变了.C++仍保留两个不同的标识符空间,但与C不同,当您只在类标识符空间中定义符号时,不需要提供struct/class关键字:
// C++
struct S {
int x;
}; // S defined as a class
void f( S a ); // correct: struct is optional
Run Code Online (Sandbox Code Playgroud)
搜索规则有哪些变化,而不是定义标识符的位置.编译器将搜索全局标识符表,并且在S未找到之后,它将S在类标识符内搜索.
之前呈现的代码行为方式相同:
typedef struct S {
int x;
} T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
Run Code Online (Sandbox Code Playgroud)
在S第二行中定义函数之后,编译器无法自动解析struct S,并且要创建对象或定义该类型的参数,您必须回退到包含struct关键字:
// previous code here...
int main() {
S();
struct S s;
}
Run Code Online (Sandbox Code Playgroud)
Kei*_*son 121
struct并且typedef是两个非常不同的东西.
所述struct关键字被用来定义,或指代,结构类型.例如,这个:
struct foo {
int n;
};
Run Code Online (Sandbox Code Playgroud)
创建一个名为的新类型struct foo.这个名字foo是一个标签 ; 只有当它紧跟在struct关键字之后才有意义,因为标签和其他标识符位于不同的名称空间中.(这与namespaces 的C++概念相似,但更为局限.)
A typedef,尽管名称,但没有定义新类型; 它只是为现有类型创建一个新名称.例如,给定:
typedef int my_int;
Run Code Online (Sandbox Code Playgroud)
my_int是一个新名称int; my_int并且int是完全相同的类型.同样,根据struct上面的定义,您可以写:
typedef struct foo foo;
Run Code Online (Sandbox Code Playgroud)
该类型已有名称,struct foo.该typedef声明给出了同样类型的新名称,foo.
语法允许您将a struct和typedef一个声明组合在一起:
typedef struct bar {
int n;
} bar;
Run Code Online (Sandbox Code Playgroud)
这是一个常见的习语.现在,您可以将此结构类型称为as struct bar或as bar.
请注意,typedef名称在声明结束前不可见.如果结构包含指向自身的指针,则可以使用该struct版本来引用它:
typedef struct node {
int data;
struct node *next; /* can't use just "node *next" here */
} node;
Run Code Online (Sandbox Code Playgroud)
一些程序员将使用不同的标识符作为struct标签和typedef名称.在我看来,没有充分的理由; 使用相同的名称是完全合法的,并使它们更清楚,它们是相同的类型.如果必须使用不同的标识符,至少使用一致的约定:
typedef struct node_s {
/* ... */
} node;
Run Code Online (Sandbox Code Playgroud)
(就个人而言,我更喜欢省略typedef并将类型称为struct bar.typedef保存一点点输入,但它隐藏了它是一种结构类型的事实.如果你想要类型不透明,这可能是一件好事.如果客户端代码n将按名称引用成员,然后它不是不透明的;它显然是一个结构,在我看来将它称为结构是有意义的.但是很多聪明的程序员在这一点上不同意我的观点.准备阅读和理解以任何一种方式编写的代码.)
(C++有不同的规则.给定声明,即使没有typedef struct blah,你也可以引用类型blah.使用typedef可能会使你的C代码更像C++ - 就像 - 如果你认为这是一件好事.)
R S*_*hko 89
另一个没有指出的区别是给结构命名(即struct myStruct)也可以让你提供结构的前向声明.所以在其他文件中,您可以写:
struct myStruct;
void doit(struct myStruct *ptr);
Run Code Online (Sandbox Code Playgroud)
无需访问定义.我建议你将两个例子结合起来:
typedef struct myStruct{
int one;
int two;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
这为您提供了更简洁的typedef名称的便利,但仍然允许您在需要时使用完整的结构名称.
Meh*_*ari 55
在C(而不是C++)中,您必须声明结构变量,如:
struct myStruct myVariable;
Run Code Online (Sandbox Code Playgroud)
为了能够使用myStruct myVariable;,您可以typedef使用结构:
typedef struct myStruct someStruct;
someStruct myVariable;
Run Code Online (Sandbox Code Playgroud)
您可以将struct定义和typedefs 组合在一个声明匿名struct和声明的语句中typedef.
typedef struct { ... } myStruct;
Run Code Online (Sandbox Code Playgroud)
RED*_*AIR 31
如果你struct没有使用typedef,你总是要写
struct mystruct myvar;
Run Code Online (Sandbox Code Playgroud)
写这是非法的
mystruct myvar;
Run Code Online (Sandbox Code Playgroud)
如果您使用,typedef则不再需要struct前缀.
Chr*_*oph 23
在C中,结构,联合和枚举的类型说明符关键字是必需的,即您始终必须在类型的名称(其标记)前面加上struct,union或者enum在引用类型时.
您可以使用a来删除关键字typedef,这是一种信息隐藏形式,因为在声明对象时,实际的对象类型将不再可见.
因此,建议(例如,参见Linux内核编码样式指南,第5章)仅在您确实要隐藏此信息时执行此操作,而不仅仅是保存几个键击.
应该使用a的示例typedef是opaque类型,它只与相应的访问器函数/宏一起使用.
以下代码使用别名创建匿名结构myStruct:
typedef struct{
int one;
int two;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
如果没有别名,则无法引用它,因为您没有为结构指定标识符.
你不能使用前向声明typedef struct.
它struct本身是一个匿名类型,因此您没有实际名称来转发声明.
typedef struct{
int one;
int two;
} myStruct;
Run Code Online (Sandbox Code Playgroud)
这样的前瞻性声明不起作用:
struct myStruct; //forward declaration fails
void blah(myStruct* pStruct);
//error C2371: 'myStruct' : redefinition; different basic types
Run Code Online (Sandbox Code Playgroud)
与其他构造typedef一样,用于为数据类型提供新名称。在这种情况下,这样做主要是为了使代码更简洁:
struct myStruct blah;
Run Code Online (Sandbox Code Playgroud)
与
myStruct blah;
Run Code Online (Sandbox Code Playgroud)
当你使用时,差异就在于struct.
你要做的第一种方式:
struct myStruct aName;
Run Code Online (Sandbox Code Playgroud)
第二种方法允许您删除关键字struct.
myStruct aName;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
658568 次 |
| 最近记录: |