习题6.3
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <sys/utsname.h>
-
-
int main(void)
-
{
-
struct utsname *nptr;
-
int tmp;
-
-
/* 定义指针后,在后面使用时要先分配空间 */
-
nptr = (struct utsname *)malloc(sizeof(struct utsname));
-
-
if ((tmp = uname(nptr)) < 0) {
-
fprintf(stderr, "uname errorn");
-
exit(1);
-
}
-
-
printf("%st%st%st%st%sn", nptr->sysname, nptr->nodename, nptr->release,
-
nptr->version, nptr->machine);
-
-
exit(0);
-
}
注意程序中的注释部分。
习题6.5
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <time.h>
-
-
#define MAXSIZE 128
-
-
int main(void)
-
{
-
time_t cal;
-
struct tm *tmptr;
-
char formatArr[MAXSIZE];
-
-
/* tmptr = (struct tm *)malloc(sizeof(struct tm)); */
-
-
if ((cal = time(NULL)) == -1) {
-
fprintf(stderr, "time errorn");
-
exit(1);
-
}
-
tmptr = localtime(&cal);
-
strftime(formatArr, MAXSIZE, "%Y %m %d %B %T %Zn", tmptr);
-
printf("%s", formatArr);
-
-
exit(0);
-
}
注:
习题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中的一段源代码
-
#include <time.h>
-
-
/* The C Standard says that localtime and gmtime return the same pointer. */
-
struct tm _tmbuf;
-
-
-
/* Return the `struct tm' representation of *T in local time,
-
using *TP to store the result. */
-
struct tm *
-
__localtime_r (t, tp)
-
const time_t *t;
-
struct tm *tp;
-
{
-
return __tz_convert (t, 1, tp);
-
}
-
weak_alias (__localtime_r, localtime_r)
-
-
-
/* Return the `struct tm' representation of *T in local time. */
-
struct tm *
-
localtime (t)
-
const time_t *t;
-
{
-
return __tz_convert (t, 1, &_tmbuf);
-
}
-
libc_hidden_def (localtime)
-
struct tm *
-
__tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
-
{
-
long int leap_correction;
-
int leap_extra_secs;
-
-
if (timer == NULL)
-
{
-
__set_errno (EINVAL);
-
return NULL;
-
}
-
-
__libc_lock_lock (tzset_lock);
-
-
/* Update internal database according to current TZ setting.
-
POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
-
This is a good idea since this allows at least a bit more parallelism. */
-
tzset_internal (tp == &_tmbuf && use_localtime, 1);
-
-
if (__use_tzfile)
-
__tzfile_compute (*timer, use_localtime, &leap_correction,
-
&leap_extra_secs, tp);
-
else
-
{
-
if (! __offtime (timer, 0, tp))
-
tp = NULL;
-
else
-
__tz_compute (*timer, tp, use_localtime);
-
leap_correction = 0L;
-
leap_extra_secs = 0;
-
}
-
-
if (tp)
-
{
-
if (! use_localtime)
-
{
-
tp->tm_isdst = 0;
-
tp->tm_zone = "GMT";
-
tp->tm_gmtoff = 0L;
-
}
-
-
if (__offtime (timer, tp->tm_gmtoff - leap_correction, tp))
-
tp->tm_sec += leap_extra_secs;
-
else
-
tp = NULL;
-
}
-
-
__libc_lock_unlock (tzset_lock);
-
-
return tp;
-
}
最后返回的指针指向localtime中定义的struct tm _tmbuf
阅读(1469) | 评论(0) | 转发(0) |