2013-02-24 66 views
0

我希望这个问题有一个简单的答案,所以请耐心等待我。如果我有一个C头文件定义类型为这样: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; 
} 

回答

1

这似乎是使用->代替.的一个简单的问题。如果你有TYPE *temp,你会使用->

这应该工作:

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

我在发帖前试过这个,得到了上面提到的错误。任何想法为什么? – user2103459 2013-02-24 00:21:38

+0

@ user2103459您需要更改'#define',请参阅编辑。 – Dukeling 2013-02-24 00:25:49

+1

@ user2103459注意到了哪里?看不到任何错误消息。 – junix 2013-02-24 00:26:45

2

由于问题发生变化,我改变我的回答有点:

基本类型定义是正确的,该代码太。唯一错误的是在createExample中使用example的实例:在声明堆栈变量时,不得使用“ - >”运算符来访问字段。你必须使用'。'运营商。所以正确访问字段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; 

而且如果它是按值返回结构是一个好主意,因为这意味着从和堆栈区复制他们,你应该考虑每次。根据结构的大小,这可能会在某些情况下导致堆栈崩溃。也许你应该考虑动态分配,并在某些时候传递指针。

+0

请注意,该问题已被修改(而不是由我),使typedef名称变为'Example'。 – 2013-02-24 00:32:45

+0

@JonathanLeffler感谢您的提示。将重做我的答案。 – junix 2013-02-24 00:34:39

+0

谢谢,我可以做的唯一更改就是createExample函数。我尝试使用该结构已经失败。 – user2103459 2013-02-24 00:36:11

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; 
} 

Notationally,这种使用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()相反的直观属性,使它不够理想(值得注意的是,它不保证空终止,但它确实保证覆盖目标缓冲区中的每个字节(直到指定的长度),即使源字符串很多比目标缓冲区短)。