gpt4 book ai didi

c - 访问其范围之外的本地声明的结构

转载 作者:行者123 更新时间:2023-12-05 03:13:58 25 4
gpt4 key购买 nike

我想将数据写入结构数组。结构本身在 main() 中声明和定义。我有 3 个函数需要写入、处理和读取数组中的数据。我所能做的就是创建一个全局结构声明,然后将指针传递给它们。

是否可以不将结构声明设为全局?

相关代码贴在下面

这是我在 main() 之外的结构声明

struct date
{
int d;
int m;
int y;
};
struct stud
{
int roll;
char name[30];
struct date dob;
int P;
int C;
int M;
float PCM;
char flag_in;
char flag_pro;
};

这些是函数定义。

 void getdata(struct stud *S)
{
scanf("%d", &(S->roll));
scanf("%s", (S->name));
//Similarly for dob, p, c, m
(S->flag_in)='1';
return;
}

void process(struct stud *S)
{
if(S->flag_in=='1')
{
S->PCM=(S->P + S->C + S->M)/3;
S->flag_pro='1';
}
}

void display(struct stud *S)
{
for(int x=0; x<10; x++)
if(S[x].flag_in=='1')
{
//printing the data to the console output
}
}

这些是函数调用:

getdata(&S[i]);
process(&S[x]);
display(S);

最佳答案

不想将程序的其他部分暴露给类型的内部结构是完全正确的。

C 非常适合以相当优雅的方式做到这一点。

称这个为 X.h

//Declaration of X as pointing to an incomplete struct XS.
//This says there's such a thing as a struct XS but not how it is laid out or even how big it is.
//It also says X is a short-hand for a pointer to a mysterious XS structure.
typedef struct XS* X;

//Creates an X and returns a pointer to it. Remember to call destroyX(.) exactly once - later.
X createX(void);
//Does something with X and returns some number.
int doXThing(X x);

//Destroys an X. Must be called exactly once for each return value from createX().
void destroyX(X x);

这是 prog.c(包含您的 main(.) 函数)。

#include <stdlib.h>
#include <stdio.h>
#include "X.h"

//Now we actually define that mysterious structure.
//Other translation units will not see this.
struct XS {
int v;
} ;

//Here we have size and layout so we can actually implement it.

X createX(void){
X x=malloc(sizeof(struct XS));//Explicit allocation of 'implementation struct'.
if(x==NULL){
return NULL;//malloc(.) failed.
}
x->v=0;
return x;
}

int doXThing(X x){
return (x->v)++;
}

void destroyX(X x){
free(x);
}

int main(void) {
X x=createX();

printf("%d\n",doXThing(x));
printf("%d\n",doXThing(x));
printf("%d\n",doXThing(x));

destroyX(x);

return 0;
}

请注意,使用 #include "X.h" 的其他模块看不到结构的布局。好处是实现可以正常更改而无需重新编译 - 只需重新链接即可。不利的一面是,如果无法访问 X 的大小和布局,那些“使用”模块需要将所有工作委托(delegate)给一个可以执行的模块!这意味着所有 X 都必须来自自由存储(或实现模块内的静态池......)。

这个模型真的很常见,也很强大,因为它允许完全抽象和数据隐藏。

如果您愿意进行大量转换,您甚至不需要“透露”名称 XS

typedef XSHandle* X;

甚至

typedef unsigned short* X; //Little used type... Illegal but works on most platforms - check your documentation of use char (bare, signed or unsigned).

但不要陷入:

typedef void* X;

在 C 中,void* 的转换非常困惑,您会遇到麻烦的!然而,C++ 在这方面的表现要好得多。

PS:将实现放在与main(.)相同的翻译单元中是不正常的。在一个小项目中这并没有错,但在一个小项目中进行如此多的抽象是不正常的。

PPS: 声明此方法提供了非常高的 OO 编程。有趣的是,Stroustrup 做出了有记录的设计决定,不对 C++ 中的所有类都这样做,因为它有固定且不可避免的开销,他给自己一个“零开销原则”,并希望提供一种“混合”抽象的方法直接访问对象布局(分配为局部变量、直接访问成员、内联函数……)。

我认为他做出了正确的决定,作为 C++ 预期用途的语言级别决定。在适当的情况下,这并不会使它成为糟糕的设计模式。

关于c - 访问其范围之外的本地声明的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27763407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com