018-时间处理库,预处理
⼀、C语⾔的时间处理库
time.h是C/C++中的⽇期和时间头⽂件,通过他可以获取系统时间及时间格式 转换
time库中常⽤函数介绍
1、函数名称: time
2、函数名称: localtime
3、函数名称: asctime
4、函数名称: ctime
5、函数名称: gmtime
6、函数名称:mktime
7、函数名称:difftime
1.time
函数原型:time_t time(time_t * timer)
功能: 获取当前的系统时间,返回的结果是⼀个time_t类型, 其中time_t是⼀ 个⻓整型,⼀般⽤来表示⽤1970年以来的秒数。返回⾃纪元Epoch(1970-01-01 00:00:00 UTC)起经过的时间秒数,UTC时间也即是格林尼治标准时间 GMT(世界协调时间)。 如果参数timer是⼀个空指针,函数会返回⼀个time_t的⻓整形。如果不是空指 针,函数将结果存放到timer指针指向的内存单元中。
测试源码:
time_t t= time(NULL); // typedef long time_t; /* time value*/
printf("time :%ld\n",(long)t);
//time函数也常⽤于随机数的⽣成,⽤⽇历时间作为种⼦。
#include <stdio.h>
#include <time.h>
#include<stdlib.h>
int main(void)
{
int i;
srand((unsigned) time(NULL));
printf("ten random numbers from 0 to 99\n\n");
for(i=0;i<10;i++)
{
printf("%d\n",rand()%100);
}
return 0;
}
2.gmtime
函数原型:struct tm *gmtime(const time_t *timep);
将time_t表示的秒数时间转换为我们⽇常可以理解的时间 函数的参数timep是⼀个表示当前时间秒数的指针。 返回值⼀个tm类型的结构体指针。
struct tm { //tm结构体在头⽂件time.h中定义
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};
其中需要注意的是:
1、tm_hour 表示的是UTC的时间,没有经过时区转换
2、tm_mon ⽉份范围是:0-11. 所以打印时需要加⼀。
3、tm_year 年份是从1900年开始的年数,所以打印时需要加1900。
测试源码:
#include <stdio.h>
#include <time.h>
time_t t = time(NULL);
printf("time :%ld \n", (long)t);
struct tm *gt;
gt = gmtime(&t);
printf("gt->tm_sec \t:%d \n", gt->tm_sec);
printf("gt->tm_min \t:%d \n", gt->tm_min);
printf("gt->tm_hour \t:%d \n", gt->tm_hour); //是UTC时间,未经时区转换
printf("gt->tm_mday \t:%d \n", gt->tm_mday);
printf("gt->tm_mon+1 \t:%d \n", gt->tm_mon+1); //范围是0-11
printf("gt->tm_year+1900 :%d \n", gt->tm_year+1900); //从1900年开始的年数
printf("gt->tm_wday \t:%d \n", gt->tm_wday);
printf("gt->tm_yday \t:%d \n", gt->tm_yday);
printf("gt->tm_isdst \t:%d \n", gt->tm_isdst);
3.ctime
函数原型:char *ctime(const time_t *timep);
函数功能: 将时间转换成⼀个可以识别的字符串格式
函数返回值:成功返回时间字符串,失败返回NULL. 函数的参数timep是⼀个表示当前时间秒数的指针。
asctime 函数与 ctime 函数返回的字符串格式是相同的。
区别在于输⼊的格式不同:
ctime asctime 函数:输⼊ struct tm 格式的时间。
ctime 函数:输⼊ time_t 格式的时间。
4.asctime
函数原型: char* asctime(struct tm * ptr)
功能:它也是⼀种字符串格式化函数,将tm格式的时间转换为 ⼀个字符串格式。
函数返回: 返回的时间字符串格式为:星期,⽉,⽇,⼩时:分:秒,年
参数说明: 结构指针ptr应通过函数localtime()和gmtime()得到
5.localtime
函数名称: localtime
函数原型: struct tm *localtime(const time_t *timer)
函数功能: 返回⼀个以tm结构表达的机器时间信息(本地时间)
参数说明: timer-使⽤time()函数获得的机器时间
6.mktime
函数原型:time_t mktime(struct tm *tm);
功能:将⼀个tm格式时间转换成秒数。
返回值: 成功返回time_t格式的时间,失败返回(time_t)-1。
mktime 函数的作⽤是,把 struct tm 格式的时间,转换为 time_t 格式的时间
需要注意的是,给 mktime 函数输⼊的 struct tm 参数为本地时间(即 经过时区转换之后的时间)。 从上⾯的截图也可以看出:
输⼊参数不为1时:
使⽤ localtime 转换后的本地时间。再经过 mktime 函数转换后,前后两个时间戳是相同的。
输⼊参数为1时:
使⽤ gmtime 转换后的UTC时间。再经过 mktime 函数转换后,前后两个时间戳是不同的。
7.difftime
头⽂件:#include
定义函数: double difftime(time_t time2, time_t time1);
函数说明: 返回两个time_t型变量之间的时间间隔,即 计算两个时刻之间的时间差。
8.gettimeofday
在C语⾔中可以使⽤函数gettimeofday()函数来得到时间。它的精度可以达到微秒
#include <sys/time.h>
int gettimeofday(struct timeval*tv,struct timezone *tz )
gettimeofday()会把⽬前的时间⽤tv 结构体返回,当地时区的信息则放到tz所指的结构中
1>timeval
struct timeval{
long tv_sec;/*秒*/
long tv_usec;/*微妙*/
};
2>timezone 结构定义为:
struct timezone{
int tz_minuteswest;/*和greenwich 时间差了多少分钟*/
int tz_dsttime;/*type of DST correction*/
}
二、预处理
1.基本概念
预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。预处理是C语言的一个重要功能, 它由预处理程序负责完成。当对一个源文件进行编译时, 系统将自动引用预处理程序对源程序中的预处理部分作处理, 处理完毕自动进入对源程序的编译。
C语言提供了多种预处理功能,如宏定义、文件包含、 条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、 移植和调试,也有利于模块化程序设计。
经过预处理后程序可由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。
C提供的预处理功能主要有以下三种:
1.宏定义
2.文件包含
3.条件编译
这些功能分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与一般C语句相区别,这些命令以符号“#”开头。例如:
#define
#include
#ifdef
2.宏定义
宏定义一般形式为:
#define 标识符 字符串
例如:# define PI 3.1415926
- 宏定义的作用是在本程序文件中用指定的标识符PI来代替“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的PI都用“3.1415926”代替。这种方法使用户能以一个简单的名字代替一个长的字符串.
- 这个标识符(名字)称为“宏名”
- 在预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏定义命令。
带参数的宏定义一般形式为:
#define 宏名(参数表) 字符串
字符串中包含在括弧中所指定的参数
例如:#define S(a,b) a*b
area=S(3,2);
- 程序中用3和2分别代替宏定义中的形式参数a和b,用
3*2
代替S(3,2) 。因此赋值语句展开为:area=3*2
带参数的宏和函数的区别:
(1) 函数调用时,先求出实参表达式的值,然后代入形参。而使用带参的宏只是进行简单的字符替换。
(2) 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
(3) 对函数中的实参和形参类型要求一致。而宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以是任何类型的数据
3.“文件包含”处理
所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来。C语言提供了#include命令用来实现“文件包含”的操作。
其一般形式为:
#include "文件名"
或
#include <文件名>
说明:
(1) 一个#include命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include命令。
(2) 在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。
(4) 在#include命令中,文件名可以用双撇号或尖括号括起来。
(5) 被包含文件(file2.h)与其所在的文件(即用#include命令的源文件file2.c),在预编译后已成为同一个文件(而不是两个文件)。因此,如果file2.h中有全局静态变量,它也在file1.h文件中有效,不必用extern声明。
防止重复包含
// mytest.h 此段宏的意思是如果定义了宏变量MYTEST_H_则不再定义它
#ifndef MYTEST_H_
#define MYTEST_H_
//头文件内容
#endif
4.条件编译
**概念:**所谓“条件编译”,是对部分内容指定编译的条件,使其只在满足一定条件才进行编译。
条件编译命令的几种形式:
(1)#ifdef 标识符
程序段1
#else
程序段2
#endif
(2)#ifndef 标识符
程序段1
#else
程序段2
#endif
(3) #if 表达式
程序段1
#else
程序段2
#endif
例 :输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。
#include <stdio.h>
#define LETTER 1
void main()
{
char str[20]="C Language",c;
int i;
i=0;
while((c=str[i])!=‘\0’)
{
i++;
#if LETTER
if(c>='a' && c<='z')
c=c-32;
#else
if(c>='A' && c<='Z')
c=c+32;
#endif
printf("%c",c);
}
}
运行结果为:
C LANGUAGE