0

我希望这个问题有一个简单的答案,所以请耐心等待。如果我有一个 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;
}
4

3 回答 3

2

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

基本上TYPE定义是正确的,代码也是正确的。唯一错误的是使用examplein的实例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;

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

于 2013-02-24T00:13:48.693 回答
1

->使用 a而不是 a似乎是一个简单的问题.

->用于指针,所以如果你有TYPE *temp你会使用->.

这应该有效:

TYPE createTask (int val, char *desc)
{
    TYPE temp;
    temp.val = val;
    strcpy(temp.description, desc);
    return temp;
}
于 2013-02-24T00:12:59.877 回答
0

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

接受你想使用TYPEpro tem,你的函数只需要一个变量 - 要么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;
}

Example从符号上讲,这始终使用 typedef 名称。如果您要使用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()使其不太理想(值得注意的是,它不保证空终止,但它保证覆盖目标缓冲区中的每个字节(直到指定的长度),即使源字符串短得多比目标缓冲区)。

于 2013-02-24T00:49:00.367 回答