Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69461
  • 博文数量: 24
  • 博客积分: 50
  • 博客等级: 民兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-24 22:12
文章分类

全部博文(24)

文章存档

2013年(24)

我的朋友

分类: LINUX

2013-03-05 21:29:36

习题6.3

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/utsname.h>

  4. int main(void)
  5. {
  6.     struct utsname *nptr;
  7.     int tmp;

  8.     /* 定义指针后,在后面使用时要先分配空间 */
  9.     nptr = (struct utsname *)malloc(sizeof(struct utsname));

  10.     if ((tmp = uname(nptr)) < 0) {
  11.         fprintf(stderr, "uname errorn");
  12.         exit(1);
  13.     }

  14.     printf("%st%st%st%st%sn", nptr->sysname, nptr->nodename, nptr->release,
  15.            nptr->version, nptr->machine);

  16.     exit(0);
  17. }
注意程序中的注释部分。

习题6.5

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. #define MAXSIZE 128

  5. int main(void)
  6. {
  7.     time_t cal;
  8.     struct tm *tmptr;
  9.     char formatArr[MAXSIZE];

  10.     /* tmptr = (struct tm *)malloc(sizeof(struct tm)); */

  11.     if ((cal = time(NULL)) == -1) {
  12.         fprintf(stderr, "time errorn");
  13.         exit(1);
  14.     }
  15.     tmptr = localtime(&cal);
  16.     strftime(formatArr, MAXSIZE, "%Y %m %d %B %T %Zn", tmptr);
  17.     printf("%s", formatArr);

  18.     exit(0);
  19. }

注:习题6.3中的指针是传递给函数的参数,在函数中实际是对该指针所指向的内存地址操作的,故而,在使用该指针是要为其分配内存。而在习题6.5中的指针是通过函数的返回值给其赋值的。localtime函数定义了一个static struct tm类型的局部静态变量,它将time_t类型数据转换并赋予static struct tm类型的局部静态变量,然后返回局部静态变量的地址。再将返回值赋给loctime。这样指针loctime指向localtime函数内部定义的静态 变量。
一个是localtime,使用的是一个全局变量。
glibc/time/localtime.c

line 23 struct tm _tmbuf;
这里是一个全局变量,如果不是线程安全的话,用的是这个全局变量来返回的值。所以这个值能够保留下来,
如果使用的是localtime_r需要自己传递进一个空间来保存结果。
localtime调用__tz_convert (t, 1, &_tmbuf);
__tz_convert函数在glibc/time/tzset.c中,结果会存到第三个参数里面。
像这样的返回static地址的代码用在多线程时就会可能发生问题,少用。

下面是localtime中的一段源代码

点击(此处)折叠或打开

  1. #include <time.h>

  2. /* The C Standard says that localtime and gmtime return the same pointer. */
  3. struct tm _tmbuf;


  4. /* Return the `struct tm' representation of *T in local time,
  5.    using *TP to store the result. */
  6. struct tm *
  7. __localtime_r (t, tp)
  8.      const time_t *t;
  9.      struct tm *tp;
  10. {
  11.   return __tz_convert (t, 1, tp);
  12. }
  13. weak_alias (__localtime_r, localtime_r)


  14. /* Return the `struct tm' representation of *T in local time. */
  15. struct tm *
  16. localtime (t)
  17.      const time_t *t;
  18. {
  19.   return __tz_convert (t, 1, &_tmbuf);
  20. }
  21. libc_hidden_def (localtime)



点击(此处)折叠或打开

  1. struct tm *
  2. __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
  3. {
  4.   long int leap_correction;
  5.   int leap_extra_secs;

  6.   if (timer == NULL)
  7.     {
  8.       __set_errno (EINVAL);
  9.       return NULL;
  10.     }

  11.   __libc_lock_lock (tzset_lock);

  12.   /* Update internal database according to current TZ setting.
  13.      POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
  14.      This is a good idea since this allows at least a bit more parallelism. */
  15.   tzset_internal (tp == &_tmbuf && use_localtime, 1);

  16.   if (__use_tzfile)
  17.     __tzfile_compute (*timer, use_localtime, &leap_correction,
  18.          &leap_extra_secs, tp);
  19.   else
  20.     {
  21.       if (! __offtime (timer, 0, tp))
  22.     tp = NULL;
  23.       else
  24.     __tz_compute (*timer, tp, use_localtime);
  25.       leap_correction = 0L;
  26.       leap_extra_secs = 0;
  27.     }

  28.   if (tp)
  29.     {
  30.       if (! use_localtime)
  31.     {
  32.      tp->tm_isdst = 0;
  33.      tp->tm_zone = "GMT";
  34.      tp->tm_gmtoff = 0L;
  35.     }

  36.       if (__offtime (timer, tp->tm_gmtoff - leap_correction, tp))
  37.         tp->tm_sec += leap_extra_secs;
  38.       else
  39.     tp = NULL;
  40.     }

  41.   __libc_lock_unlock (tzset_lock);

  42.   return tp;
  43. }
最后返回的指针指向localtime中定义的struct tm _tmbuf


阅读(1440) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~