• C专家编程 前言


    所有的C程序都做同一件事,即观察一个字符,然后啥也不干。     ---Peter Weinberger 

    Good books: 
    C Traps and Pitfalls
    The C Puzzle Book
    Obfuscated C and Other Mysteries

          C语言编程是一项技艺,需要多年历练才能达到完善的境界。想要品味出C语言的细微之处,并通过大量编写各种不同的程序成为C语言专家,则耗时甚巨。

         编程专家在多年的实践中建立了自己的技术工具箱,里面是形形色色的习惯用法、代码片段和灵活掌握的技巧。他们汲取其他成功者的经验教训,或者直接领悟他们的代码,或者在维护他人的代码时聆听他们的教诲,随着时间的推移,逐步形成了这些东西。成为C编程高手的另一种途径是自省,即在认识错误的过程中进步。 

          //错误地使用了赋值运算符和等于运算符

         #include
         int main() {
              //1.1
             if (i = 3) ; //wrong 
             //1.2
             if (i == 3) ; //right
             //1.3
             if (3 == i) ; //be supposed to suggest 
             //attempted assighment to literal
        }

        C语言的表达能力也实在是强,编译器对于“求一个表达式的值,但不使用该值”这样的语句也能接受,并且不发出任何警告,只是简单地把返回结果丢弃。

        有些lint程序已经能够检测到这类问题,但人们很容易忽视这些有用的工具。 

        //只适用于小型程序片段,现实中的程序不可如此: 
        char pear[40];   
        double peach;
        int mango = 13;
        long melon = 2001;
        关键字:char、double、int、long
        变量名:pear、peach、mango、melon

        幽默对于学习新东西是相当重要的。

        读者可以把本书当做C语言编程的思路集锦,或是C语言提示和习惯用法的集合,也可以从经验丰富的编译器作者那里汲取营养,更轻松地学习ANSI C。 

        Enforce In_Order Execution of I/O (在I/O中实行按顺序执行的方针)(IBM/Motorola/Apple PowerPC)tunefs(UNIX) 高级系统管理员用它修改文件系统的动态参数,并优化磁盘中文件块的布局。 在早期的tunefs在线手册上,也是以一个标题为“Bugs”的小节来结尾。内容如下:
        Bugs:
        这个程序本来应该在安转好的(mounted)和活动的文件系统上运行,但事实上并非如此。因为超级块(superblock)并不是保持在告诉缓冲缓冲区中,所以只有当该程序运行在未安装好的(dismounted)文件系统中时才有效。如果运行于根文件系统,系统必须重新启动。
        你可以优化一个文件系统,但不能优化一条鱼。
        如果忽略这段话,你就等着烦吧。一个UNIX里的怪物会不断地纠缠你,直到你受不了为止。 
        mounted 安装好的
        superblock 超级快
        dismounted 未安装好的

    /*
    **编程挑战 
    */
    1. 查看一下time_t的定义,它位于文件/user/include/time.h中。 
    解析:
    #ifndef _TIME_T_DEFINED
    #define _TIME_T_DEFINED
    #ifdef _USE_32BIT_TIME_T
      typedef __time32_t time_t;
    #else
      typedef __time64_t time_t;
    #endif
    #endif

    #ifndef _TIME32_T_DEFINED
    #define _TIME32_T_DEFINED
      typedef long __time32_t;
    #endif

    #ifndef _TIME64_T_DEFINED
    #define _TIME64_T_DEFINED
      __MINGW_EXTENSION typedef __int64 __time64_t;
    #endif

    #define __int64 long long

    2.编写代码,在一个类型为time_t的变量中存放time_t的最大值,然后把它传递给ctime()函数,转换为ASCII字符串中并打印出来。注意ctime()函数同C语言并没有任何关系,它只表示“转换时间” 。

    /*ctime(time_t *t)函数,转换成ASCII字符串并打印出来。注意ctime()函数同C语言没有任何关系,   *它只表示“转换时间”。
     */
    /*time_t的最大值
     */
    /*time()获得当前的时间
     *difftime()获得当前时间和time_t所能表示的最大时间值之间的差值(以秒计算)
     */ 
    #include
    #include

    int main() {
        printf("%u %u\n", sizeof(long), sizeof(time_t));
        time_t  biggest = 0x7FFFFFFF;
        //time_t biggest = 0x7FFFFFFFFFFFFFFF;
        printf("biggest = %s\n", ctime(&biggest));
        return 0;
    }
    /*ctime()函数把参数转换为当地时间,跟世界统一时间UTC(格林尼治时间)并不一致,取决于你所在   *的时区,而且现在的年份跟最大时间值的年份相差甚远
     */ 

    /* 输出:

    */ 

    #include
    #include

    int main() {
        time_t biggest = 0x7FFFFFFF;
        printf( "sizeof(time_t) = %zd\n", sizeof(time_t) );
        printf("biggest = %s\n", asctime(gmtime(&biggest)));
        return 0;
    }
    /*gmtime()函数来取得最大的UTC时间值。这个函数并不返回一个可打印的字符串
     *asctime()函数来获取一个这样的字符串
     */ 
    /*但是,我们并未大功告成。如果你采用的是新西兰的时区,就会又多出13个小时,前提是新西兰在2038年仍然采用夏令时。新西兰在1月时采用的是夏令时(因为位于南半球)。但是,由于新西兰的最东端位于日界线的东面,在那里它应该比格林尼治时间晚10小时而不是早14小时。这样,新西兰由于其独特的地理位置,不幸成为该程序的第一个Bug的受害者。
    */ 

    /* 输出:

    */ 
    如果程序设计者去掉了程序的注释,那么多少年之后,他不得不担心该程序会在UNIX平台上溢出。请修改程序,找出答案。
    1.调用time()获得当前的时间。
    2.调用difftime()获得当前时间和time_t所能表示的最大时间值之间的差值(以秒计算)。
    3.把这个值格式化为年、月、日、小时、分钟的形式,并打印出来。它是不是比一般人的寿命还要长?
    #include
    #include
    #include
    #include  

    int main( void ){
        time_t t, t2;
        long second;
        
        t = time( &t );
        t2 = LONG_MAX;
        printf( "now date and time is: %s", ctime( &t ) );
        second = difftime( t2, t );
        printf( "second = %ld\n", second );
        
        struct tm* ptm;
        ptm = localtime( &t2 );
        printf( "year = %d\n", ptm->tm_year + 1900 );
        printf( "month = %d\n", ptm->tm_mon + 1 );
        printf( "week = %d\n", ptm->tm_mday / 7 );
        printf( "day = %d\n", ptm->tm_wday );
        printf( "hour = %d\n", ptm->tm_hour );
        printf( "minute = %d\n", ptm->tm_min );
        
        return EXIT_SUCCESS;

    /* 输出:

    */ 

  • 相关阅读:
    【Mybatis编程:批量插入相册(动态SQL)】
    c++两个整数相除,如何只入不舍小数 2023/10/7 下午9:27:57
    Vue脚手架中的axios的引入,网络事件代理配置
    C#特性(Attribute)
    【kali-漏洞利用】(3.2)Metasploit基础(中):Armitage工具利用过程
    软件过程与建模学习之:Individuals,Motivation and Teams
    python处理 json, pt, csv, npy文件 -- 打开与保存
    C#难点语法讲解之委托---从应用需求开始讲解
    OOP | 封装 继承 多态
    es6中proxy如何使用
  • 原文地址:https://blog.csdn.net/weixin_40186813/article/details/126067681