5

我正在编写一个标题 timedate.h,它的开头如下:

#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_

int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
  struct tm *time;
  time->tm_year = year;
  time->tm_mon = month;
  time->tm_mday = day;
  time->tm_hour = hour;
  time->tm_min = minute;
  time->tm_sec = second;
  return mktime(time);
}

/*...*/

#endif

然后包含在我的主要 .c 文件之一中,如下所示:

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "timedate.h"

int main(int argv, char **argc)
{
/*...*/
}

在我看来,这应该可以工作,因为 time.h 在调用 timedate.h 之前包含在主代码中。但是,当我制作时,我收到以下错误:

XXXXXXXXXX$ make
gcc file2nav.c -o file2nav
In file included from file2nav.c:4:0:
timedate.h: In function ‘timetounixtime’:
timedate.h:10:7: error: dereferencing pointer to incomplete type
timedate.h:11:7: error: dereferencing pointer to incomplete type
timedate.h:12:7: error: dereferencing pointer to incomplete type
timedate.h:13:7: error: dereferencing pointer to incomplete type
timedate.h:14:7: error: dereferencing pointer to incomplete type
timedate.h:15:7: error: dereferencing pointer to incomplete type

你能帮我理解发生了什么吗?我注意到,如果我#include <time.h>在 timedate.h 中,错误就会消失......但为什么呢?它已经包含在 file2nav.c 中。

4

6 回答 6

11

在您timedate.h使用的文件中

struct tm *time;

struct tm尚未定义。您需要包含标题#include <time.h>

您的代码中的第二个问题是您使用的是未初始化的指针time。您可以使用局部变量:

struct tm time;
time.tm_year = year;

malloc指针(记住free):

struct tm* time = malloc(sizeof(struct tm));

正如 Ryan 指出的那样,更好的做法是在 in 中声明函数.h定义它们.c

/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_

int timetounixtime(int year, int month, int day, int hour, int minute, int second);

#endif

/* timedate.c */
#include "timedate.h"
#include <time.h>

int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
  struct tm time;
  time.tm_year = year;
  time.tm_mon = month;
  time.tm_mday = day;
  time.tm_hour = hour;
  time.tm_min = minute;
  time.tm_sec = second;
  return mktime(time);
}

您需要包含所有头文件才能使您的程序编译。C++ 标头顺序建议一种可能的顺序:

  • 对应的头文件
  • 必要的项目标题
  • 3rd 方库标题
  • 标准库头文件
  • 系统头文件

按照这个顺序,您将不会错过任何忘记自己包含库的头文件。(感谢乔希的这一点)。

于 2013-06-11T17:22:59.107 回答
3

您需要#include <time.h>timedate.h文件中,因为该函数timetounixtime使用其中声明的结构。该函数需要知道 astruct tm是什么,除非您包含time.h. 不过这里还有其他几个问题。

您需要为 tm 结构分配空间,如下所示:

struct tm *time = malloc(sizeof *time);

但是由于您仅在这一个功能中使用它,因此您应该这样做

struct tm time;

否则,当您开始分配时,您正在使用无效的内存。

另外,这个头文件应该分成两个文件。

/* timedate.h */
#ifndef _TIMEDATE_H_
#define _TIMEDATE_H_

int timetounixtime(int year, int month, int day, int hour, int minute, int second);

#endif

/* timedate.c */
#include "timedate.h"

int timetounixtime(int year, int month, int day, int hour, int minute, int second)
{
  struct tm time;
  time.tm_year = year;
  time.tm_mon = month;
  time.tm_mday = day;
  time.tm_hour = hour;
  time.tm_min = minute;
  time.tm_sec = second;
  return mktime(time);
}

我建议您将来使用gcc -Wall. 你会得到像这样有用的警告:

timedate.h:15:3: warning: implicit declaration of function 'mktime' [-Wimplicit-function-declaration]

^这意味着你在mktime没有声明的情况下调用函数,这是忘记的另一个症状time.h

于 2013-06-11T17:24:39.290 回答
3

您包含错误的标题,它应该是<time.h>,而不是<sys/time.h>

<sys/time.h>可能根本没有定义您尝试使用的结构。

于 2013-06-11T17:30:28.200 回答
2

不包括sys/time.h但是time.h

于 2013-06-11T17:29:27.787 回答
1

time也恰好是系统调用。我建议将变量名称更改为time其他名称,以免与系统调用发生冲突。

于 2013-06-11T17:24:20.227 回答
0

您需要从头文件中包含 time.h 头,因为它不知道 struct tm 和 mktime 符号是什么。

当 time.h 标头最终从源文件中包含时,您将需要对这些符号进行前向声明,以便它们正确链接。

于 2013-06-11T17:25:43.883 回答