我希望这个问题有一个简单的答案,所以请耐心等待我。如果我有一个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;
}
答案 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
而不是特定名称Example
或struct Example
?你最好坚持使用特定的名称。除此之外,如果你有另一个有条件地定义TYPE
的标题,那么你最终会得到非常奇怪的效果,具体取决于首先包含哪个标题。
接受您要使用TYPE
专业版,您的函数只需要一个变量 - temp
或example
。这些中的任何一个都可行并且有意义:
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()
有一些反直觉的属性使它不太理想(特别是,它不保证空终止,但它确保覆盖目标缓冲区中的每个字节(最大指定长度),即使源字符串比目标缓冲区短得多。)