一起talk C栗子吧(第一百六十九回:C语言实例--再谈内置宏)



各位看官们,大家好,上一回中咱们说的是C语言中的布尔–bool类型的例子,这一回咱们说的例子是:再谈内置宏 。闲话休提,言归正转。让我们一起talk C栗子吧!



看官们,我们在第一百二十四回中介绍了C语言中的内置宏,当时介绍了常用的内置宏_LINE__FILE_。并且介绍了如何使用它们来输出它们所在位置的行号和所在的文件名。大家都知道,这两个内置宏经常被用来在文件中添加调试信息。因为我们写的程序难免会有错误,所以需要对程序进行调试。在文件中加入内置宏后,我们通过调试可以快速地找到错误发生在哪个文件中的哪一行。这样就可以快速修改程序中的错误,进而提高了工作效率。不过有些看官在调试时不满足于文件名和行数,他们还想知道与错误有关的日期和时间,这也是我们再谈内置宏的原因。

在本章回中, 我们将和大家一起看另外两个内置宏_DATE__TIME_。它们表示程序编译的日期和时间。接下来我们通过具体的代码来说明这两个内置宏的用法,下面是详细的代码请大家参考:

#include<stdio.h>

void func()
{
    int len=2;

    while(len-- >0)
    {
        printf("sleeping ... \n");
        sleep(1);
    }

}
int main()
{
    printf("file :%s line:%d date:%s,time:%s \n",__FILE__,__LINE__,__DATE__,__TIME__);
    func();
    printf("file :%s line:%d date:%s,time:%s \n",__FILE__,__LINE__,__DATE__,__TIME__);

    return 0;
}

我们在代码中通过内置宏来输出当前的文件名和行号以及编译文件的日期和时间,下面是程序的运行结果,请大家参考:

file :test.c line:17 date:Jun 30 2016,time:20:45:39
sleeping ...
sleeping ...
file :test.c line:19 date:Jun 30 2016,time:20:45:39 

从上面的程序运行结果中可以看到该程序的文件名、编译日期和时间。不过输出了两次,之所以这样做是为了强调_TIME_宏代表的是程序的编译时间,而不是程序的运行时间。大家可以看到,我们使用内置宏输出时间时,第一次是在调用func()函数之前,第二次是在调用func()函数之后,而代码中的func()函数让程序休眠了2秒。正常来说,输出的时间应该延迟两秒,但是我们两次输出的时间是相同的,这说明该方法输出的时间不是程序的运行时间,而是程序的编译时间。这也算是一种反证法吧,哈哈。

说明了这么多,这个与日期和时间有关的内置宏有什么作用呢?看官莫急,且听我给大家娓娓道来。在实际工作的时候,我们不可能一天完成某个大型程序,因此就会有多个版本的程序。如果程序出错的时候,我们能够知道是程序编译的日期和时间,就能依据程序版本的发布日期和时间推算出发生错误的版本,在一个具体的版本中查找错误,比在多个版本中查找错误要方便一些,因为这样可以缩小的查找错误的范围,进而快速找到错误发生的原因。鉴于这个原理,我们经常使用日期和时间的内置宏来确认程序的版本。

各位看官,关于再谈内置宏的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


时间: 2024-10-17 12:28:27

一起talk C栗子吧(第一百六十九回:C语言实例--再谈内置宏)的相关文章

一起talk C栗子吧(第一百六十二回:C语言实例--套接字知识体系图)

各位看官们,大家好,上一回中咱们说的是套接字通信模型的例子,这一回咱们说的例子是:套接字知识体系图.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们, 我们在前面的章回中介绍了许多关于套接字的内容,有些看官感觉知识比较乱,不断地摇头叹气,而且还在吟诗:剪不断,理还乱,是离愁.不对,是套接字.别有一番滋味在心头.哈哈.这位看官太有才了呀,连古诗也用上了.今天我和大家一起整理下套接字的知识,到时候将会是一番喜悦的滋味在心头. 看官们,我们最开始介绍的是套接字的概念,接着介绍了套接字的属性,

一起talk C栗子吧(第三十二回:C语言实例--再谈最大公约数)

各位看官们,大家好,我们在第九回中一起说过最大公约数的例子,这一回咱们继续说该例子.闲话休提, 言归正转.让我们一起talk C栗子吧! 关于最大公约数的内容,我们在第九回中提到过,如果大家忘记了的话,可以点击这里查看原文. 我们今天继续说最大公约数,说的内容可以看作是对第九回的补充.和第九回一样,我们还是通过辗转相 除法来求最大公约数.不过我们在第九回中主要通过循环的方式来实现辗转相除法,今天我们使用另外一 种方式来实现辗转相除法. 看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家

一起talk C栗子吧(第一百六十四回:C语言实例--const关键字)

各位看官们,大家好,上一回中咱们说的是三目运算符的例子,这一回咱们说的例子是:const关键字 .闲话休提,言归正转.让我们一起talk C栗子吧! 我们在前面章回中介绍了很多系统编程接口,在这些接口的参数中经常出现const关键字,有看官对此提出了疑问"这些const有什么用处呢?".今天,我将和大家一起来解决该疑问. 在C语言中const是一种修饰符,经常用来修饰变量.使用它修饰以后的变量,就成为常量.常量是不允许被修改的.下我们举个简单的例子来说明const的用法. 1 #inc

一起talk C栗子吧(第一百五十九回:C语言实例--基于AF_INET域的数据报套接字通信)

各位看官们,大家好,上一回中咱们说的是基于AF_INET域的流套接字通信的例子,这一回咱们说的例子是:基于AF_INET域的数据报套接字通信 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在上一回中一起制作了我们的第三道佳肴是:基于AF_INET域的流套接字通信.今天,我将和大家一起制作第四道佳肴:基于AF_INET域的数据报套接字通信. 制作第四道佳肴的菜谱:数据报套接字过程. 制作第四道佳肴的食材:数据报套接字的接口,套接字属性,套接字地址信息. 看官们,以上的内容,我们

一起talk C栗子吧(第一百六十五回:C语言实例--C语言中的常量)

各位看官们,大家好,上一回中咱们说的const关键字的例子,这一回咱们说的例子是:C语言中的常量 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们, 我们在上一回中介绍了const关键字,大家都知道被const修饰的都是常量.提到常量,我们在程序中经常使用它,这一回中我们一起看看C语言中的其它常量. 大家都知道,常量的值是固定的,而且不能被修改.在C语言中,一共有四种实现常量的方式,它们分别是: 字面常量 宏 const 枚举. 接下来我们分别介绍这四种实现常量的方式. 字面常量:字

一起talk C栗子吧(第一百六十八回:C语言实例--C语言中的布尔--bool类型)

各位看官们,大家好,上一回中咱们说的是控制终端字符颜色的例子,这一回咱们说的例子是:C语言中的布尔–bool类型 .闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,在数字电路中我们经常会遇到布尔类型,其实在编写软件的过程中也会使用布尔类型.布尔类型的变量只有两种值:真和假.在实际的编程过程中,我们经常定义宏,然后使用1表示真,0表示假.下面是具体的例子: #define TRUE 1 #define FALSE 0 例子中定义了两个宏,一个是TRUE,它的值是1,表示真:另外一个是F

一起talk C栗子吧(第一百二十二回:C语言实例--多线程)

各位看官们,大家好,上一回中咱们说的是线程知识体系图的例子,这一回咱们说的例子是:多线程.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我首先给大家拜个晚年,祝大家在新的一年里身体健康,万事如意. 今天我们介绍一下多线程,我相信大家都听过这个名词,但是具体的含义是什么呢?其实多线程是指两个或者两个以上的线程在一起运行,他们共同完成某个工作. 我们在前面的章回中介绍过使用pthread_create()函数去创建线程.如果想使用多线程,那么只需要多次使用该函数去创建线程就可以.接下来

一起talk C栗子吧(第一百七十九回:C语言实例--字符和字符串输出函数二)

各位看官们,大家好,上一回中咱们说的是字符和字符串输出函数的例子,这一回咱们继续说该例子.闲 话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在上一回中介绍了字符和字符串输出函数的用法,満篇都是理论,古语云:纸上得来终觉浅,绝知此事要躬行.这一回中我们要把这些纸上得来理论应用于实践中,让我们一起动手去实践吧. 接下来,我们将通过具体的代码来说明如何使用字符输出函数,以及使用时的注意事项: int main() { char ch = 'a'; char *str = "hello

一起talk C栗子吧(第一百三十二回:C语言实例--从内存的角度看进程和线程)

各位看官们,大家好,上一回中咱们说的C程序内存布局的例子,这一回咱们说的例子是:从内存的角度看进程和线程.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们刚刚介绍完C程序的内存布局,我们趁热打铁,从内存的角度来分析一下进程和线程. 不管是进程还是线程,他们都会加载到内存中才能运行,因此他们在内存中的布局和其它C程序的内存布局完全相同.进程和线程的内存布局也分为代码区,数据区,堆区和栈区. 对进程来说,父子进程只共享代码区中的内容,父子进程拥有各自的数据区,堆区和栈区.而且它们只能