相互参照(Pg 140 K& R2) [英] mutually referential (Pg 140 K&R2)

查看:70
本文介绍了相互参照(Pg 140 K& R2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PG。 K& R2中的140个显示了一个相互参照结构的例子

声明...


struct t

{

struct s * p;

};


struct s

{

struct t * q;

};

我通过我的C编译器运行以下测试程序,看看它是否会编译:b $ b br />

#include< stdlib.h>


struct t

{

struct s * p; / *类型''struct s''在这里不可见* /

};


struct s

{

struct t * q;

};


int main()

{

printf(Hello world \ n);

返回0;

}

编译并运行没有任何明显的问题。我希望它能够b / b
抱怨我上面评论过的那条线。


如果类型''struct s''不是这样的话,它是如何有效的在范围内,当* p是

被声明为struct t类型的成员?


无效,请告诉我如何申报相互参照

结构类型。


谢谢你是

Pg. 140 of K&R2 shows an example of mutually referential structure
declarations...

struct t
{
struct s *p;
};

struct s
{
struct t *q;
};
I ran the following test program through my C compiler to see if it
would compile:

#include <stdlib.h>

struct t
{
struct s *p; /* type ''struct s'' is not visible here */
};

struct s
{
struct t *q;
};

int main()
{
printf("Hello world\n");
return 0;
}
It compiled and ran without any noticeable problems. I expected it to
complain about the line I''ve commented above.

How is this valid when the type ''struct s'' is not in scope when *p is
declared as a member of the type struct t?

If this is ''valid'' please tell me why scopes don''t apply here. If this
is ''not valid'' please tell me how I can declare mutually referential
struct types.

Thank you

推荐答案

G Patel写道:
G Patel wrote:
Pg。 K& R2中的140个显示了一个相互参照结构的例子......

struct t
结构s * p;
};

结构s
结构t * q;
};

我通过我的C编译器运行以下测试程序来查看如果它会编译:

#include< stdlib.h>

struct t
{
struct s * p; / *类型''struct s''在这里不可见* /
};

struct s
{
struct t * q;
} ;

int main()
{/> printf(" Hello world \ nn);;
返回0;
}

它编译并运行时没有任何明显的问题。我希望它能够抱怨我上面评论过的这一行。

当* p是
如果这是''有效'',请告诉我为什么范围不适用于此处。如果这个无效,请告诉我如何申报相互参照
结构类型。

谢谢
Pg. 140 of K&R2 shows an example of mutually referential structure
declarations...

struct t
{
struct s *p;
};

struct s
{
struct t *q;
};
I ran the following test program through my C compiler to see if it
would compile:

#include <stdlib.h>

struct t
{
struct s *p; /* type ''struct s'' is not visible here */
};

struct s
{
struct t *q;
};

int main()
{
printf("Hello world\n");
return 0;
}
It compiled and ran without any noticeable problems. I expected it to
complain about the line I''ve commented above.

How is this valid when the type ''struct s'' is not in scope when *p is
declared as a member of the type struct t?

If this is ''valid'' please tell me why scopes don''t apply here. If this
is ''not valid'' please tell me how I can declare mutually referential
struct types.

Thank you



以下代码将两个结构放在范围内。第一个struct

t;是不必要的,但它证明了这一点。


#include< stdio.h>


struct s;

struct t;


struct t {

struct s * p;

};

struct s {

struct t * q;

};


int main(void){

printf(Hello world \ n);

返回0;

}



The following code will place both structs in scope. The first "struct
t;" is unnecessary, but it demonstrates the point.

#include <stdio.h>

struct s;
struct t;

struct t {
struct s *p;
};

struct s {
struct t *q;
};

int main(void) {
printf("Hello world\n");
return 0;
}


在文章< 11 ********************** @ g14g2000cwa.googlegroups .com>

G Patel< ga********@gmail.com>写道:
In article <11**********************@g14g2000cwa.googlegroups .com>
G Patel <ga********@gmail.com> wrote:
Pg。 K& R2中的140个显示了相互参照结构的示例
声明...


[垂直压缩]

struct t {struct s *磷;结构s {struct t * q; };


[snippage]

当* p被声明为*时,如果类型''struct s''不在范围内,这是如何有效的struct t的类型成员?


结构 - 这是C'的通用目的创建一个新类型

thingy - 可以声明,以及定义。


这种声明的最小语法是:


struct tag;


而使用标签[%]的定义的最小语法是:


struct tag {FIRST_MEMBER;换句话说,如果没有开括号,你只需要提到一个类型的* name *,而不是定义那个类型。 (大括号内的内容

定义了类型本身。)


[%脚注:通过省略

标签。由于名称

不能再重复,因此其用途相对有限。另一方面,有可能bb捕获。使用C'的typedef指定未命名的类型名称关键字,

- 尽管它的名字 - 实际上并没有定义新的类型。相反,

它定义了现有类型的别名。如果您在某些替代别名下捕获无名

类型,则可以使用别名。这有点像是指Clark Kent作为超人:如果Clark

肯特没有真名,你就不得不称他为超人

甚至在伪装时也是如此。 :-)]


给定一个类型名称,你当然可以声明那个

类型的变量,以及指向该类型的指针,依此类推:


int i; / *这意味着i是一个int * /

char * cp; / *这意味着* cp是一个char。 * /


对于您自己的类型也是如此:


struct type1 s1; / *即,s1是type1。 * /

struct type2 * s2; / *即,* s2是type2。 * /


如果您已经定义了类型,这很好;如果你还没有定义你的类型,那么它就是C所谓的不完整类型。

你有时(但不总是)声明普通变量

类型不完整;你可以随时声明指向不完整的

类型的指针。 (更具体地说 - 更令人困惑的是 - 如果T是

不完整类型,T *,指针指向T,本身就是一个完整的类型。

它只是指向一个不完整的类型。)

如果这是''有效'',请告诉我为什么范围不适用于此。
Pg. 140 of K&R2 shows an example of mutually referential structure
declarations...
[Vertically compressed]
struct t { struct s *p; };
struct s { struct t *q; };
[snippage]
How is this valid when the type ''struct s'' is not in scope when *p is
declared as a member of the type struct t?
Structures -- which are C''s general-purpose "create me a new type"
thingy -- can be declared, as well as defined.

The minimal syntax of such a declaration is:

struct tag;

while the minimal syntax of a definition that uses a tag[%] is:

struct tag { FIRST_MEMBER; };

In other words, without the open brace, you are merely mentioning
the *name* of a type, rather than defining that type. (The contents
inside the braces define the type itself.)

[%footnote: New structure types can be left un-named by omitting
the tag. This has relatively limited usefulness since the name
cannot then be repeated. On the other hand, it is possible to
"capture" the un-named type name using C''s "typedef" keyword, which
-- despite its name -- does not actually define new types. Instead,
it defines aliases for existing types. If you capture the no-name
type under some alternative alias, you can use the alias. It is
a bit like referring to either Clark Kent as Superman: if Clark
Kent had not had a real name, you would have had to call him Superman
even when he was in disguise. :-) ]

Given a type-name, you can of course declare variables of that
type, and pointers to that type, and so on:

int i; /* this means "i" is an "int" */
char *cp; /* this means *cp is a "char" */

The same holds true for your own types:

struct type1 s1; /* i.e., s1 is a "type1" */
struct type2 *s2; /* i.e., *s2 is a "type2" */

If you have already defined your type, this is fine; if you have
not yet defined your type, it is what C calls an "incomplete type".
You can sometimes, but not always, declare ordinary variables that
have incomplete types; you can always declare pointers to incomplete
types. (More specifically -- and more confusingly -- if T is an
incomplete type, "T *", pointer-to-T, is itself a complete type.
It merely points to an incomplete type.)
If this is ''valid'' please tell me why scopes don''t apply here.



范围实际上可以在这里适用:


struct s {long l; };


void f(无效){

struct s; / *这个空的声明清除方式* /


struct s {char c; } var;

/ *这是一个新的,不同的类型,也叫s * /

......

}
<但是,请注意,范围是由

函数f()的定义引入的,而不是结构成员周围的大括号。 (这个
是C和C ++不同的一个领域:在C ++中,结构成员可以

有自己的范围,仅限于结构.C ++规则是

比C规则复杂得多。)


我意识到这也令人困惑。我建议永远不要这样做,在

中,就像我推荐的代码一样:


int number_of_zorgs;

void f (无效){

int number_of_zorgs;

...

}


我们这里有两个普通的int具有相同名称的变量。如果我们试图在

同时讨论这两个变量,那么
会变得混乱,因为它们都有相同的名称。 (由于我自己的

给定的名字很常见,我有很多个人经验

有这个问题。有时我在一个有两三个人的小组/>
克里斯在其中。有时候人们求助于我们编号。)


尽管如此,让我们重新审视相互指责

结构问题。鉴于:


struct s; / *声明类型s而不定义它* /

struct t; / *和类似t * /

struct s {struct t * tp; }; / *现在定义s * /

struct t {struct s * sp; }; / *和t * /


很容易看到s。间接(通过指针)

指的是t,而t指的是t。间接地指s。我们提前宣布了两个

,然后定义了两个。


C然而,让我们变得草率。我们提到它时,类型名称只会弹出

(当然,使用C'的类型名称创建

关键字struct) 。所以我们不必事先声明两种类型的

- 我们可以开始定义一个,并在第一个中间声明另一个
的定义。这是你在示例代码中所拥有的



这有一些问题。 Typos偷偷溜进来,早先在另一个帖子中指出了

。如果我们声明或定义一个名为

" gargleblaster"的类型,很容易将名称错误输入为garbleblaster

(garG => garB)在某些时候:


struct gargleblaster; / *也可以在这里插入{contents} * /

...

extern void somefunc(struct garbleblaster *);


我们从未声明(更少定义)拼写错误的名称,因此它只是作为一种新的不完整类型而存在。 (有些人使用

这作为使用typedef的参数;并且它是一个有效的参数

,尽管我自己的口味以另一种方式运行。)


结构类型* do *服从范围(尽管没有他们的b
)。一般来说,不完整的结构类型只能在同一范围内完成(可以在

内部范围内完成它们,但实际应用相对较少) 。

不幸的是,对于这个特殊情况,函数原型参数

有原型范围,结束 - 永远无法复活

- 在结束原型序列的闭括号处。因此

函数声明somefunc()声明一个不完整的类型

(garbleblaster,我们拼写错误的gargleblaster),它永远不会是b / b $ b完成。更好的编译器通常会在这里发出警告。

然而,在你理解了整个

段之前,警告是令人困惑的。

-

In-Real-Life:风河系统Chris Torek

美国犹他州盐湖城(40°39.22''N,111°50.29''W)+1 801 277 2603

电子邮件:忘了它 http: //web.torek.net/torek/index.html

由于垃圾邮件发送者,阅读电子邮件就像在垃圾中搜索食物一样。



Scopes can in fact apply here:

struct s { long l; };

void f(void) {
struct s; /* this "vacuous" declaration clears the way */

struct s { char c; } var;
/* this is a new, different type also named s */
...
}

Note, however, that the scope is introduced by the definition of
function f(), not the braces around the structure members. (This
is one area where C and C++ differ: in C++, structure members can
have their own scope, limited to the structure. The C++ rules are
much more complicated than the C rules.)

I realize this is also confusing. I recommend never doing it, in
the same way that I recommend against code like:

int number_of_zorgs;
void f(void) {
int number_of_zorgs;
...
}

Here we have two ordinary "int" variables with the same name. It
becomes confusing if we attempt to talk about both variables at
the same time, since they both have the same name. (Since my own
given name is quite common, I have a lot of personal experience
with this problem. Sometimes I am in a group that has two or three
"Chris"es in it. Sometimes people resort to numbering us.)

With all that out of the way, let us revisit the mutually-referential
structure issue. Given:

struct s; /* declare type s without defining it */
struct t; /* and likewise for type t */

struct s { struct t *tp; }; /* now define s */
struct t { struct s *sp; }; /* and t */

it is easy enough to see that an "s" refers indirectly (via pointer)
to a "t", and a "t" refers indirectly to an "s". We declared both
ahead of time, and then defined both.

C, however, allows us to be sloppy. A type-name simply springs
into existence as soon as we mention it (using C''s type-name-creating
keyword "struct", of course). So we do not have to declare the
two types in advance -- we can just start defining one, and declare
the other in the middle of the first one''s definition. This is
what you had in your sample code.

There are some problems with this. Typos sneak in, as pointed out
in another thread earlier. If we declare or define a type called
"gargleblaster", it is easy to mis-type the name as "garbleblaster"
(garG => garB) at some point:

struct gargleblaster; /* optionally, insert { contents } here too */
...
extern void somefunc(struct garbleblaster *);

We never declared (much less defined) the misspelled name, so it
simply springs into existence as a new incomplete type. (Some use
this as an argument for using typedefs; and it is a valid argument
for that, despite my own tastes running the other way.)

Structure types *do* obey scopes (despite having none of their
own). In general, incomplete structure types are only usefully
completed in the same scope (it is possible to complete them in an
inner scope, but this has relatively little practical application).
Unfortunately for this particular case, function prototype arguments
have "prototype scope", which ends -- and can never be resurrected
-- at the close parenthesis ending the prototype sequence. Thus
the declaration of function somefunc() declares an incomplete type
("garbleblaster", our misspelled "gargleblaster") that can never
be completed. Better compilers generally produce a warning here.
The warning is, however, confusing until you understand this whole
paragraph.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22''N, 111°50.29''W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.


G Patel写道:
G Patel wrote:
Pg。 K& R2中的140个显示了一个相互参照结构的例子......

struct t
结构s * p;
};

结构s
结构t * q;
};

我通过我的C编译器运行以下测试程序来查看如果它会编译:

#include< stdlib.h>

struct t
{
struct s * p; / *类型''struct s''在这里不可见* /
};

struct s
{
struct t * q;
} ;

int main()
{/> printf(" Hello world \ nn);;
返回0;
}

它编译并运行时没有任何明显的问题。我希望它能够抱怨我上面评论过的这一行。

当* p是
如果这是''有效'',请告诉我为什么范围不适用于此处。如果这个无效,请告诉我如何声明相互引用的结构类型。
Pg. 140 of K&R2 shows an example of mutually referential structure
declarations...

struct t
{
struct s *p;
};

struct s
{
struct t *q;
};
I ran the following test program through my C compiler to see if it
would compile:

#include <stdlib.h>

struct t
{
struct s *p; /* type ''struct s'' is not visible here */
};

struct s
{
struct t *q;
};

int main()
{
printf("Hello world\n");
return 0;
}
It compiled and ran without any noticeable problems. I expected it to
complain about the line I''ve commented above.

How is this valid when the type ''struct s'' is not in scope when *p is
declared as a member of the type struct t?

If this is ''valid'' please tell me why scopes don''t apply here. If this
is ''not valid'' please tell me how I can declare mutually referential
struct types.




struct s * p声明p使用不完整的struct s类型,稍后用struct s {...}完成

。不完整的类型仅适用于大括号,例如

枚举,联合和结构iirc。



struct s *p declares p using an incomplete struct s type, which is later completed
with struct s {...}. Incomplete types apply only to curly bracket things like
enums, unions, and structs iirc.


这篇关于相互参照(Pg 140 K&amp; R2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆