【问题标题】:Sending array of structures to function将结构数组发送给函数
【发布时间】:2014-07-08 20:10:31
【问题描述】:

为了完成一个更大的项目,我试图了解如何将结构数组和 char* 类型的标记发送到函数。我这段代码的目的是做以下事情:

  • 打开文件
  • 标记文件
  • 向搜索函数发送令牌和结构数组
  • search 函数会遍历arrayofstructures,使用strcmp 查找与token 匹配的对象
    • 如果找到匹配返回 1,主函数将检查 1 或 0
    • 如果为 0,则不向结构数组添加标记,如果为 1,则向结构数组添加标记

我刚刚写了一个小程序来看看我是否可以将数组和令牌发送到一个函数并进行比较,但是我得到了很多错误,我不知道该怎么做,因为我不明白大多数错误。

#include <stdio.h>
#include <string.h>

int search(struct id array[],char* tok);

struct id
{
    char name[20];
    int age;
};

int main(void)
{
    struct id person[2] = { {"John Smith", 25},
                            {"Mary Jones", 32} };
    char* token = "Mary Jones"; /*char* for strtok() return type*/
    search(person,token);
}

int search(struct id array[],char* tok)
{
    int i,value;int size = 2;
    for(i=0;i<size;i++)
    {
        if(strcmp(array[i].name,tok) == 0)
            value = 0;
        else
            value = 1;
    }
    return value;
}

【问题讨论】:

  • 所以,套用第一段,您对数组和指针一无所知,但仍然有一个大项目需要最后的润色?好奇。
  • 不是它的最后润色,我正在构建它。我对指针和结构有一个想法,但是当谈到向函数发送东西时,我总是搞砸了。

标签: c function structure


【解决方案1】:

地点

int search(struct id array[],char* tok);  

struct 声明之后。并将search 的返回值分配给int 变量。

int found = search(person,token);  
if(found == 0)
    printf("Name is found\n"); // or whatever you want

【讨论】:

    【解决方案2】:

    这是您应该使用的代码。

    #include <stdio.h>
    #include <string.h>
    
    struct id
    {
        char name[20];
        int age;
    };
    
    int search( const struct id array[], size_t n, const char *tok );
    
    int main( void )
    {
        struct id person[2] = { {"John Smith", 25},
                                {"Mary Jones", 32} };
        char* token = "Mary Jones"; /*char* for strtok() return type*/
    
        printf( "%d\n", search( person, sizeof( person ) / sizeof( *person ), token ) );
    
        return 0;
    }
    
    
    int search( const struct id array[], size_t n, const char *tok )
    {
        size_t i = 0;
    
        while ( i < n && strcmp( array[i].name, tok ) != 0 ) ++i;
    
        return n != 0 && i != n;
    }
    

    编辑:我删除了一些错别字。

    输出是

    1
    

    那个名字已经找到了。

    考虑到如果找到名称,正确的函数搜索必须返回 1。:)

    【讨论】:

    • sizeof(person)/sizeof(*person) 会返回什么?数组中的元素总数为 2?
    • @user368 sizeof( person ) 返回为数组分配的字节数。 sizeof( *person ) 返回数组的一个元素(即第一个元素)中的字节数。因此,将第一个除以第二个,您将得到数组中元素的数量。
    【解决方案3】:

    始终在定义指向它们的指针之前声明结构/枚举/联合,或者在函数声明中使用它们,如下所示:

    struct id;
    

    额外提示,同时引入一个与标签名相同id的typedef-name:

    typedef struct id id;
    

    总是在第一次使用之前声明函数,像这样:

    int search(struct id array[],char* tok);
    

    在将结构/枚举/联合用于除第一条规则之外的任何内容之前,请始终定义它们,如下所示:

    struct id {
        char name[20];
        int age;
    };
    

    使用 typedef-name:

    typedef struct id { /**/ } id;
    

    现在,在可能的情况下,将定义放在您需要放置前向声明的位置。
    唯一的例外:如果您将声明放在头文件中,那很好。
    这减少了多余的冗余。


    更多观察:

    • 不要对名称等使用固定大小的字段。它们总是太短。
    • 永远不要修改字符串文字,如果不注意禁止导致未定义的行为,您的程序就会变得毫无意义。改为使用副本。

      /* Most implementations supply this non-standard function */
      char* strdup(const char* s) {
        size_t n = strlen(s)+1;
        char* p = malloc(n);
        if(p) memcpy(p, s, n);
        return p;
      }
      
    • 当你传递一个数组时,你实际上只是传递了一个指向它的第一个元素的指针,所以也要传递一个元素计数。
      • size_tssize_t 类型专为这项工作而设计。
      • 如果您有一个名为a 的数组,您可以使用sizeof a / sizeof *a 获取元素计数。但请确保这不是指针!
    • 早退为好:早退成功。
      这样您就不会忘记您在下一次循环迭代中的成功(就像发生在您身上的那样),而且速度更快。

    【讨论】:

    • 固定大小的字段没问题,只要确保不会溢出它们。 (这比确保每次创建、复制或销毁对象时都插入特殊代码要少一些戏剧性)。
    猜你喜欢
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多