C:创建一个struct,返回一个TYPE

时间:2013-02-24 00:07:23

标签: c struct

我希望这个问题有一个简单的答案,所以请耐心等待我。如果我有一个C头文件定义TYPE:

struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
};

typedef struct Example Example;

# ifndef TYPE
# define TYPE      Example
# define TYPE_SIZE sizeof(Example)
# endif

然后在.c文件中,我有一个函数如下:

TYPE createExample (int val, char *desc) {
}

从主要调用

TYPE newEx;
char desc[EXAMPLE_DESC_SIZE], filename[50], *nlptr;
int val;

newEx = createExample(val, desc);

如何编写createExample代码以使其返回TYPE?我尝试了以下(以及其他一些不成功的尝试):

TYPE createExample (int val, char *desc)
{
    TYPE temp;
    struct Example example;
    example->val = val;
    strcpy(example->description, desc);

    return temp = example;
}

3 个答案:

答案 0 :(得分:2)

随着问题的改变,我改变了我的回答:

基本上TYPE定义是正确的,代码也是如此。唯一不对的是在example中使用createExample的实例:当你声明一个堆栈变量时,你不能使用“ - >”运营商访问字段。你必须使用'。'运营商。因此,val字段的正确访问权限是example.val = val。这就是你的编译器通过

告诉你的
  

'' - >'的无效类型参数。

仍然

struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
};

typedef struct Example Example;

可以缩短为

typedef struct Example {
    char description[EXAMPLE_DESC_SIZE];    
    int val;                          
}Example;

你应该考虑按值返回结构是否是个好主意,因为这意味着每次都要从堆栈区域复制它们。根据结构的大小,这可能会在某些情况下打击您的堆栈。也许你应该考虑动态分配并在某些时候传递指针。

答案 1 :(得分:1)

使用->代替.似乎是一个简单的问题。

->仅供参考,因此,如果您使用TYPE *temp,则需要使用->

这应该有效:

TYPE createTask (int val, char *desc)
{
    TYPE temp;
    temp.val = val;
    strcpy(temp.description, desc);
    return temp;
}

答案 2 :(得分:0)

反问题:为什么要使用通用名称TYPE而不是特定名称Examplestruct Example?你最好坚持使用特定的名称。除此之外,如果你有另一个有条件地定义TYPE的标题,那么你最终会得到非常奇怪的效果,具体取决于首先包含哪个标题。

接受您要使用TYPE专业版,您的函数只需要一个变量 - tempexample。这些中的任何一个都可行并且有意义:

TYPE createExample(int val, char *desc)
{
    struct Example example;
    example.val = val;
    strcpy(example.description, desc);

    return example;
}

请注意从->.的更改;你正在处理一个本地结构,而不是一个指向结构的指针。

TYPE createExample(int val, char *desc)
{
    TYPE temp;
    temp.val = val;
    strcpy(temp.description, desc);

    return temp;
}

就个人而言,我更愿意看到:

Example createExample(int val, char *desc)
{
    Example example;
    example.val = val;
    strncpy(example.description, desc, sizeof(example.description)-1);
    example.description[sizeof(example.description)-1] = '\0';
    return example;
}

在符号上,它始终使用typedef名称Example。如果您打算使用struct Example,请不要使用typedef。

另一个更改可确保初始化不会导致缓冲区溢出。在这个阶段,防止像这样的缓冲区溢出对你来说可能有点异国情调,但它非常谨慎。还有其他方法可以做到这一点,例如:

size_t len = strlen(desc);
if (len >= sizeof(example.description))
    len = sizeof(example.description) - 1;
memmove(example.description, desc, len);
example.description[len] = '\0';

我可能会用这个; strncpy()有一些反直觉的属性使它不太理想(特别是,它不保证空终止,但它确保覆盖目标缓冲区中的每个字节(最大指定长度),即使源字符串比目标缓冲区短得多。)