简体   繁体   English

如何在函数中捕获结构声明

[英]How to capture a struct declaration in function

I have the following c code: 我有以下C代码:

struct {
    short s;
    int n;
} variableName;

I want to write a function to capture this variable like so 我想写一个函数来捕获这个变量,像这样

void func(MyStruct* var){
    //do stuff
}

func(&variableName);

I would like to do this without providing a definition for the struct. 我想这样做而不提供结构的定义。 Is there a way to capture variableName? 有没有办法捕获variableName?

No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually: 不,您不能在C函数中传递“匿名”结构。您当然可以定义函数以单独接受参数:

void func(short s, int n) { ... }

Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. 或者,您可以在函数和调用代码都可见的地方定义MyStruct结构。 Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be). 请注意,执行此操作时,整个结构均按值(副本)传递,这可能是您想要的(或可能不是)行为。

You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. 您可能正在寻找更多其他语言提供的“字典”或“关联数组”或“哈希”类型的东西,其中包含任意键值对。 Pure C does not have a facility for this; 纯C没有为此提供便利; the compiler wants to know the layout of a structure in advance. 编译器希望事先知道结构的布局。

(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.) (我不确定您是否会问一个更深奥的想法,那就是隐藏结构的组成并将“不透明的句柄”传递到API之中或之外。在C语言中有多种结构方法,但是请说出来,如果那是您要说的话。)

Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" 完全被忽略“我想在不提供结构定义的情况下执行此操作。有没有办法捕获variableName?” in the OP, unless it was edited after. 在OP中,除非它在之后进行了编辑。 The question makes less sense now, but heres how you could normally pass a struct to a function for future readers. 现在,这个问题变得不那么有意义了,但是在这里,您通常如何将结构传递给函数以供将来的读者使用。

#include <stdio.h>

    struct StructName{
        short s;
        int n;
    };

    void func(struct StructName struct_var){
            printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
        }

    int main(){
        struct StructName struct_var;
        struct_var.s = 0xDEAD;
        struct_var.n = 0xBEEF;
        func(struct_var);
    }

//It looks like you are trying to use the definition as a variable. //似乎您正在尝试将定义用作变量。 Here the definition is StructName and the variable is struct_var. 这里的定义是StructName,变量是struct_var。

this sample code outputs: Param values are: DEAD BEEF 此示例代码输出: 参数值为:DEAD BEEF

If you use clang or gcc, you may be able to use typeof : 如果您使用clang或gcc,则可以使用typeof

struct foo {
    struct {
        int i;
    } anon;
} foo;

void do_something(typeof(foo.anon)* member) {
    member->i = 1;
}

If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon) . 如果没有您类型的全局实例,则可以使用typeof((struct foo){}.anon)

This comes with a lot of downsides. 这有很多缺点。 The most obvious ones are that: 最明显的是:

  • it's not standard, and it ties you to clang/gcc 这不是标准的,它使您与clang / gcc联系在一起
  • it's pretty darn ugly 这真是丑陋
  • it might not behave as you expect anyway 无论如何,它可能无法达到您的预期

For instance, structurally-equivalent anonymous types do not have the same type, so in something like this: 例如,结构上等效的匿名类型具有相同的类型,因此如下所示:

struct foo {
    struct {
        int i;
    } anon1;
    struct {
        int i;
    } anon2;
} foo;

anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both. anon1anon2都具有不同类型的,这意味着typeof它们中的一个不能被用于指这两者。

In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. 从长远来看,您几乎可以肯定会发现命名结构是值得的,特别是如果将它们用作函数参数。 For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous. 例如,如果您想使标头中的变量可用,我认为您将必须努力使其保持匿名。

Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load: 尽管它不是特别漂亮并且与C ++不兼容,但是C将嵌套声明的名称放在全局名称空间中,因此这是可移植的,并且对前载的代码更改不是很大:

struct {
    struct not_anon {
        int i;
    } anon;
} foo;

void do_something(struct not_anon* member) {
    member->i = 1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM