5
#include<stdio.h>
struct str 
{ 
   static int a ;
    int b ;
 } s ;
int main()
{
static int p , k ;
printf("%d %d",sizeof(p),sizeof(s));
getchar();
return 0;
}

上面的代码给出了错误。但是,如果我将结构的第一个成员重新定义为“int”而不是“静态 int”,那么它运行良好。为什么结构中不允许使用静态成员,其意义是什么?

4

5 回答 5

7

C 语言中根本没有这样的功能。在 C 语言中,这种特性没有有意义的概念框架。

您会看到,在 C++ 术语中,成员变量和普通全局变量之间只有一个相关区别static:声明其名称的范围和相应的命名语法。可以调用全局变量a,同时调用类的静态成员SomeClass::a。除了范围命名之外,没有其他区别。(我故意忽略了其他特定于 C++ 的特性,比如访问控制,因为它们在 C 中不存在,而这个问题实际上是关于 C 的。)

在 C 语言中,结构类型不会引入自己的作用域。没有像 SomeStruct::aC 语言那样的命名语法。出于这个原因,根本没有理由在结构中拥有静态成员。您可以改为声明一个全局变量并达到相同的效果。调用您的全局变量str_a以传达将其“关联”的意图,struct str并将该变量视为struct str.

从形式上讲,在C++中也可以这样做,即完全忽略C++语言的这一特性,使用全局函数和变量,而不是类内部的静态函数和变量。但是,这样做会放弃 C++ 的所有成员访问控制功能。而且这些功能真的很值得拥有。C 语言没有访问控制功能,这意味着在 C 语言中 [几乎] 什么都没有。

于 2012-08-08T06:21:29.870 回答
0

不,不是在 C 中。我相信 C++ 可以做到这一点,这意味着在结构的所有实例之间共享一个副本。astruct str

如果你想在 C 中做类似的事情,你有几个选择(可能还有更多,我现在想不出它们)。

首先是使用以下内容分解公共变量:

int struct_str_static_a;
struct str {
    int b;
} s;

这样,a结构的所有实例只共享一个副本——每个实例仍然有自己的b.

对此稍作修改是引入指向该公共变量的指针并初始化指针:

int struct_str_static_a;
struct str {
    int *pA;
    int b;
} s;
:
s.pA = &struct_str_static_a;

然后你可以使用*(s.pA)where 之前你会使用s.a. 因为每个 的实例struct str都有自己的pA指向单个 的指针a,这会给您带来类似的效果。然而,这是一条曲折的道路。

第三种选择是让自己加入下一个 ISO C 工作组,并将其作为对语言的更改提出来。然而,在接下来的十年左右,这需要你自己付出相当多的努力,可能不值得付出努力:-)

于 2012-08-08T06:22:36.640 回答
0

你在这里有很好的答案:http: //cboard.cprogramming.com/c-programming/123691-static-variable-structure.html

一般来说,将其声明为静态并没有任何好处,但如果您仍然希望它,您可以迁移到 c++ 或将整个结构声明为静态。

于 2012-08-08T06:23:00.320 回答
0

静态修饰符是在文件的全局范围内声明您的变量,而函数中的静态修饰符会创建一个变量,其持久值仅限于该函数的范围。而且你不能在你的结构实例之间共享这个整数的值。这在 C 中不支持,也不能支持;)

为什么要在结构中使用静态成员?也许有(必须有)更好的解决方案。

于 2012-08-08T06:21:28.277 回答
0

只是语言不允许。除了它不是设计的一部分之外,没有更深层的原因。您始终可以使用单独的全局变量实现相同的行为,如下所示:

struct str
{
    int b;
} s;

int str_a;

请注意,在您的结构中使用静态将是完全不同int a;的,这将是每个type 对象的不同子元素struct str

(另请注意,在从 C 演变而来的语言 C++ 中,静态类成员确实存在并且行为与我上面描述的解决方法完全相同,只是全局变量的名称与类的名称紧密相关。)

于 2012-08-08T06:20:59.347 回答