在结构体中的函数中传递枚举(C 语言)

发布于 2024-11-16 16:29:29 字数 1398 浏览 4 评论 0原文

我已经查找了如何在函数中传递枚举,但是当函数和枚举都在结构中声明时,该方法不起作用。这是我的代码:

test_setup.h:

     1 #ifndef TEST_SETUP_H_
     2 #define TEST_SETUP_H_
     3 #include <stdio.h>
     4 #include <stdlib.h>
     5 
     6 
     7 typedef struct _test_setup {
     8 
     9   int *partner;            
    10   int *send_first;         
    11   double *results;         
    12 
    13   enum { CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE } SomeMatches;
    14   void match_partners(SomeMatches match);
    15 
    16 } test_setup;              
    17 
    18 #endif

test_setup.c :

     1 #include "../includes/test_setup.h"
     2 
     3 void match_partners(SomeMatches match) { 
     4   if (match == CHIP_WIDE) {
     5 
     6   }
     7   else if (match == NODE_WIDE) {
     8 
     9   }
    10   else if (match == SYSTEM_WIDE) {
    11 
    12   }
    13   else {
    14 
    15   }
    16 }`

错误:

    In file included from src/test_setup.c:1:
    src/../includes/test_setup.h:14: error: expected ‘)’ before ‘match’
    src/../includes/test_setup.h:16: warning: no semicolon at end of struct or union
    src/test_setup.c:3: error: expected ‘)’ before ‘match’
    make: *** [setup.o] Error 1

我尝试了声明枚举并在函数参数中使用它的每种组合,但没有任何效果。任何想法将不胜感激。我正在使用 mpicc 进行编译(因为程序的其余部分使用 MPI 函数),但我尝试过使用 GNU GCC,但得到了相同的警告/错误。

I have looked up how to pass an enumeration in a function, but that method doesn't work when both the function and enumeration are declared in a structure. Here is my code :

test_setup.h:

     1 #ifndef TEST_SETUP_H_
     2 #define TEST_SETUP_H_
     3 #include <stdio.h>
     4 #include <stdlib.h>
     5 
     6 
     7 typedef struct _test_setup {
     8 
     9   int *partner;            
    10   int *send_first;         
    11   double *results;         
    12 
    13   enum { CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE } SomeMatches;
    14   void match_partners(SomeMatches match);
    15 
    16 } test_setup;              
    17 
    18 #endif

test_setup.c :

     1 #include "../includes/test_setup.h"
     2 
     3 void match_partners(SomeMatches match) { 
     4   if (match == CHIP_WIDE) {
     5 
     6   }
     7   else if (match == NODE_WIDE) {
     8 
     9   }
    10   else if (match == SYSTEM_WIDE) {
    11 
    12   }
    13   else {
    14 
    15   }
    16 }`

Error:

    In file included from src/test_setup.c:1:
    src/../includes/test_setup.h:14: error: expected ‘)’ before ‘match’
    src/../includes/test_setup.h:16: warning: no semicolon at end of struct or union
    src/test_setup.c:3: error: expected ‘)’ before ‘match’
    make: *** [setup.o] Error 1

I have tried every combination of declaring an enumeration and using it in the function parameters, but nothing has worked. Any ideas would be much appreciated. I am compiling with mpicc (because the rest of the program uses MPI functions) but I have tried with GNU GCC and I get the same warnings/errors.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

茶花眉 2024-11-23 16:29:29

对于C

如果你真的想要C,那么你根本不能做任何这些。

  • 不能在结构中定义成员函数
  • 不能定义嵌套在结构中的命名枚举

对于 C++

使用作用域解析运算符 ::

#include<iostream>

struct Test
{
  enum SomeEnum { TEST1, TEST2, TEST3 };
  void SomeFunction(SomeEnum e);
};

void Test::SomeFunction(Test::SomeEnum e)
{
  std::cout << e << "\n";
}

int main(int argc, char* argv[])
{
  Test t;
  t.SomeFunction(Test::TEST1);
  return 0;
}

For C

If you truly want C, then you simply can't do any of this.

  • You can't define a member function in a struct
  • You can't define a named enumeration nested in a struct

For C++

Use the scope-resolution operator ::

#include<iostream>

struct Test
{
  enum SomeEnum { TEST1, TEST2, TEST3 };
  void SomeFunction(SomeEnum e);
};

void Test::SomeFunction(Test::SomeEnum e)
{
  std::cout << e << "\n";
}

int main(int argc, char* argv[])
{
  Test t;
  t.SomeFunction(Test::TEST1);
  return 0;
}
待天淡蓝洁白时 2024-11-23 16:29:29

如果您想在 C 中执行此操作,这里有解决方法:

// define the enumeration at file scope:

typedef enum {CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE} SomeMatches;

// declare a *pointer* to a function in the struct:
typedef struct { 
    int *partner;
    int *send_first;
    double *results;

    void (*match_partners)(SomeMatches match);   
} test_setup;

像平常一样定义您的函数:

void match_partners(SomeMatches match)
{
  if (match == CHIP_WIDE) {}
  else if (match == NODE_WIDE) {}
  else if (match == SYSTEM_WIDE) {}
}

然后,当您创建结构体的实例时,分配函数指针:

test_setup t;
t.match_partners = match_partners;

您不需要显式取消引用函数指针来调用它,因此,您可以执行您的函数,

t.match_partners(CHIP_WIDE);

就好像您想要显式取消引用它一样,请使用

(*t.match_partners)(CHIP_WIDE);

注意,C 没有任何与 this 指针等效的东西;如果 match_partners 取决于结构实例中包含的信息,则必须将该实例作为单独的参数显式传递:

void match_parthers(SomeMatches matches, test_setup *instance) 
{
}
...
typedef struct {
  ...
  void (*match_partners)(SomeMatches matches, test_setup *instance);
  ...
} test_setup;
...
test_setup t;
t.match_partners = match_partners;
t.match_partners(CHIP_WIDE, &t);

请注意,为了使结构定义合法,我们必须将该实例作为指针,因为此时 test_setup 类型尚未完成。

编辑

最后一句话不是很清楚;让我再试一次。结构体定义不能引用其自身的实例,因为在结束 } 之前,结构体类型不完整。 IOW,以下内容是不合法的:

struct foo
{
  ...
  struct foo bar;
  ...
};

但是,结构可以引用指向同一类型的另一个实例的指针,因此以下内容是合法的:

struct foo
{
  ...
  struct foo *bar;
  ...
};

相同的逻辑适用于函数指针声明; instance 参数需要声明为 test_setup *,因为此时 test_setup 类型定义尚未完成。正如 Merlyn 在评论中指出的那样,您可能希望实例是可变的,但该语言要求您在这种情况下使用指针。

If you want to do this in C, here are the workarounds:

// define the enumeration at file scope:

typedef enum {CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE} SomeMatches;

// declare a *pointer* to a function in the struct:
typedef struct { 
    int *partner;
    int *send_first;
    double *results;

    void (*match_partners)(SomeMatches match);   
} test_setup;

Define your function as normal:

void match_partners(SomeMatches match)
{
  if (match == CHIP_WIDE) {}
  else if (match == NODE_WIDE) {}
  else if (match == SYSTEM_WIDE) {}
}

Then when you create an instance of the struct, assign the function pointer:

test_setup t;
t.match_partners = match_partners;

You don't need to explicitly dereference the function pointer to call it, so you can execute your function as

t.match_partners(CHIP_WIDE);

although if you want to dereference it explicitly, use

(*t.match_partners)(CHIP_WIDE);

Note that C doesn't have any equivalent to the this pointer; if match_partners depends on information contained in the struct instance, you'll have to explicitly pass that instance as a separate argument:

void match_parthers(SomeMatches matches, test_setup *instance) 
{
}
...
typedef struct {
  ...
  void (*match_partners)(SomeMatches matches, test_setup *instance);
  ...
} test_setup;
...
test_setup t;
t.match_partners = match_partners;
t.match_partners(CHIP_WIDE, &t);

Note that for the struct definition to be legal, we have to pass the instance as a pointer, since the test_setup type isn't complete at that point.

EDIT

That last sentence isn't terribly clear; let me try again. A struct definition cannot refer to an instance of itself, because the struct type isn't complete until the closing }. IOW, the following is not legal:

struct foo
{
  ...
  struct foo bar;
  ...
};

However, a struct can refer to a pointer to another instance of the same type, so the following is legal:

struct foo
{
  ...
  struct foo *bar;
  ...
};

The same logic applies to the function pointer declaration; the instance parameter needs to be declared as test_setup *, since the test_setup type definition isn't complete at that point. As Merlyn points out in the comments, you probably want the instance to be mutable anyway, but the language requires you to use a pointer in that circumstance.

海未深 2024-11-23 16:29:29

您的枚举没有正确的名称(它没有标签),并且无法从代码中的不同点引用。试试这个:

enum SomeMatches { CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE };
struct _test_setup {
     /* ... */
     enum SomeMatches SomeMatches;
     void (*match_partners)(enum SomeMatches match);
     /* ... */
};

随意撒上typedefs,或者让东西裸露......

Your enum does not have a proper name (it doesn't have a tag) and cannot be referenced from distinct points in the code. Try this:

enum SomeMatches { CHIP_WIDE, NODE_WIDE, SYSTEM_WIDE };
struct _test_setup {
     /* ... */
     enum SomeMatches SomeMatches;
     void (*match_partners)(enum SomeMatches match);
     /* ... */
};

Sprinkle typedefs at will, or leave things bare ...

白芷 2024-11-23 16:29:29

首先,#define TEST_SETUP_H_ 位于 #ifndef TEST_SETUP_H_ 之前。否则你的代码将被编译器完全注释掉。

您不能像这样命名 typedef 结构:
typedef 结构体名称{
/内容/
};

void match_partners(SomeMatches match) 可以是 void match_partners(void) 并在函数内使用该变量,因为使用该头文件,您已将其设为全局并且不需要通过它。

First of all #define TEST_SETUP_H_ goes before #ifndef TEST_SETUP_H_. Otherwise your code will be completely commented out to the compiler.

You don't name a typedef struct like that it goes as such:
typedef struct struct_name{
/contents/
};

void match_partners(SomeMatches match) can be void match_partners(void) and use the variable inside the function because with that header file you've made it global and don't need to pass it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文