【问题标题】:function definition not found in h file在 h 文件中找不到函数定义
【发布时间】:2022-01-03 14:38:48
【问题描述】:

我不太明白 Visual Studio 2019 想要我做什么(C 语言)。一方面,它不会向我抛出错误或警告,但另一方面,它会在我的 API 文件中用绿色波浪线标记我的 createCustomer 声明。我想封装 Customer 并在 Customer 结构上使用 ADT。

这些是我的源文件和头文件:

客户.h

#include <stdlib.h>

typedef struct Customer
{
    unsigned int customerId;
    const char* name;
    int numOrders;
}Customer, * CustomerPtr;

客户.c

#include "customer.h"

#define MAX_NO_OF_CUSTOMERS 10
static Customer objectPool[MAX_NO_OF_CUSTOMERS];
static unsigned int customersCount = 0;

CustomerPtr createCustomer(const char* name, size_t numOrders)
{
    CustomerPtr newCustomer_p = NULL;
    if(customersCount < MAX_NO_OF_CUSTOMERS)
    {
        newCustomer_p = objectPool + (customersCount++);
        newCustomer_p->name = name;
        newCustomer_p->numOrders = numOrders;
    }
}

customer_api.h

#include "customer.h"

CustomerPtr createCustomer(const char* name, int numOrders);

main.c

#include <stdio.h>
#include "main.h"
#include "customer_api.h"

int main()
{
    CustomerPtr customer_p = createCustomer("Demo", 5);
    return 0;
}

正如我所说,在customer_api.h 下,下面的CustomerPtr createCustomer(const char* name, int numOrders); 在函数声明createCustomer 下有波浪线。程序编译并成功运行,没有错误/警告。

也许我没有正确使用 API h 文件概念?我试图让客户属性实现对外部文件隐藏,所以在其他文件中,我只需要在需要访问客户模块时包含customer_api.h

【问题讨论】:

  • 只激活警告,createCustomer 不会返回任何内容
  • 如果将鼠标悬停在曲线上,会弹出什么消息?
  • 您的声明有一个int 第二个参数,但您的定义有size_t。不同的功能。
  • 但正如@Ôrel 指出的那样,该函数格式不正确,据我所知,您发布的代码确实不能(或不应该)成功运行。 (它可能似乎起作用,因为您没有尝试使用在main 中的调用不是返回的指针。)
  • “我正在尝试对外部文件隐藏客户属性实现...” 您无法隐藏放在头文件中的任何内容,即使它使用不同的名称。处理此问题的正确方法是在标头中将 Customer+typedef 前向声明为 CustomerPtr,在 customer.h 中编写仅引用 CustomerPtr 的 API,并在customer.c 文件。

标签: c api include


【解决方案1】:

一方面它不会向我抛出错误或警告……

您应该在项目设置中启用所有警告;请参阅:Why should I always enable compiler warnings? 启用警告后,您的代码(或我粘贴到 VS 2019 IDE 中的代码版本)会生成 5 个警告:

警告 C4255:'main':未给出函数原型:将 '()' 转换为 '(无效)'
警告 C4189:“customer_p”:局部变量已初始化 但未参考
警告 C4028:形参 2 不同于 声明
警告 C4267:“=”:从“size_t”转换为“int”, 可能丢失数据
警告 C4716:“createCustomer”:必须返回一个 价值

现在,#1、#2 和 #4 可以放在一边(暂时);大问题是 #3 和 #5。

要解决#3:您需要使函数定义(在“customer.c”中)中的参数与原型中(在“customer_api.h”中)中的参数相同;据推测,由于结构的numOrders 成员是int,您应该将前者更改为具有int 第二个参数(这也解决并删除了警告#4):

解决 #5:createCustomer 函数必须返回它声明返回的内容:CustomerPtr 对象。局部变量newCustomer_p 是明显的候选对象。

这是该函数的“固定”版本:

CustomerPtr createCustomer(const char* name, int numOrders)
{
    CustomerPtr newCustomer_p = NULL;
    if (customersCount < MAX_NO_OF_CUSTOMERS) {
        newCustomer_p = objectPool + (customersCount++);
        newCustomer_p->name = name;
        newCustomer_p->numOrders = numOrders;
    }
    return newCustomer_p;
}

这会留下警告 #1 和 #2。要修复 #1,请将 void 添加为 main 的参数列表(空括号实际上并不定义 C 中的函数)。大概,你会在某个时候对未使用的变量做一些事情,这样就可以解决#2。

int main(void) // Note the EXPLICIT void argument list; () just means "unspecified" in C
{
    CustomerPtr customer_p = createCustomer("Demo", 5);
    // Do something with "customer_p"
    (customer_p);
    return 0;
}

……但另一方面,它用绿色的波浪线标记了我。

将鼠标悬停在曲线上会显示问题:“找不到‘createCustomer’的函数定义。”这是由生成警告 #3 的问题引起的;解决绿色曲线的修复。

【讨论】:

    【解决方案2】:

    要使 Customer 类型的实现对客户端模块隐藏,您需要将结构定义放在 C 文件中。这是一种方法。在下面的代码中,我将 CustomerPtr 简称为 Customer,因为我认为它更简洁。为了简单和一致,最好使用与客户数据类型相同的客户实现和头文件名称。我还建议为Customer.h 中的每个函数使用前缀Customer_。我还做了一些其他的调整。

    客户.h

    #ifndef CUSTOMER_H
    #define CUSTOMER_H
    
    #include <stdlib.h>
    
    typedef struct CustomerDesc *Customer;
    
    Customer Customer_Create(const char *name, size_t numOrders);
    
    #endif
    

    客户.c

    #include "Customer.h"
    
    #define LEN(array) (sizeof (array) / sizeof (array)[0])
    
    struct CustomerDesc {
        unsigned int customerId;
        const char *name;
        int numOrders;
    };
    
    static struct CustomerDesc objectPool[10];
    static unsigned int customersCount = 0;
    
    Customer Customer_Create(const char *name, size_t numOrders)
    {
        Customer newCustomer = NULL;
        if (customersCount < LEN(objectPool)) {
            newCustomer = objectPool + customersCount;
            newCustomer->name = name;
            newCustomer->numOrders = numOrders;
            customersCount++;
        }
        return newCustomer;
    }
    

    main.c

    #include "Customer.h"
    
    int main(void)
    {
        Customer customer = Customer_Create("Demo", 5);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-13
      • 2011-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多