返回介绍

18.1 SYSTEMTIME 的例子

发布于 2025-02-22 14:00:47 字数 3260 浏览 0 评论 0 收藏 0

让我们看看 Win32 结构体 SYSTEMTIME 的定义:

清单 18.1: WinBase.h

#!cpp
typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;

让我们写一个获取当前时间的 C 程序:

#!cpp
#include <windows.h>
#include <stdio.h>
void main()
{
SYSTEMTIME t;
    GetSystemTime (&t);
    printf ("%04d-%02d-%02d %02d:%02d:%02d
",
    t.wYear, t.wMonth, t.wDay,
    t.wHour, t.wMinute, t.wSecond);
    return;
};

反汇编结果如下(MSVC 2010):

清单 18.2: MSVC 2010

#!bash
_t$ = -16 ; size = 16
_main PROC
    push ebp
    mov ebp, esp
    sub esp, 16 ; 00000010H
    lea eax, DWORD PTR _t$[ebp]
    push eax
    call DWORD PTR __imp__GetSystemTime@4
    movzx ecx, WORD PTR _t$[ebp+12] ; wSecond
    push ecx
    movzx edx, WORD PTR _t$[ebp+10] ; wMinute
    push edx
    movzx eax, WORD PTR _t$[ebp+8] ; wHour
    push eax
    movzx ecx, WORD PTR _t$[ebp+6] ; wDay
    push ecx
    movzx edx, WORD PTR _t$[ebp+2] ; wMonth
    push edx
    movzx eax, WORD PTR _t$[ebp] ; wYear
    push eax
    push OFFSET $SG78811 ; ’%04d-%02d-%02d %02d:%02d:%02d’, 0aH, 00H
    call _printf
    add esp, 28 ; 0000001cH
    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0
_main ENDP

在本地栈上程序为这个结构体分配了 16 个字节:这正是 sizeof(WORD)*8 的大小(因为结构体里有 8 个 WORD)。 请注意结构体是由 wYear 开始的,因此,我们既可以说这是“传给 GetSystemTime() 函数的,一个指向 SYSTEMTIME 结构体的指针”,也可以说是它“传递了 wYear 的指针”。这两种说法是一样的!GetSystemTime() 函数会把当前的年份写入指向的 WORD 指针中,然后把指针向后移动 2 个字节(译注:WORD 大小为 2 字节),再写入月份,以此类推。 事实上,结构体的成员其实就是一个个紧贴在一起的变量。我可以用下面的方法来访问 SYSTEMTIME 结构体,代码如下:

#!cpp
#include <windows.h>
#include <stdio.h>
void main()
{
    WORD array[8];
    GetSystemTime (array);
    printf ("%04d-%02d-%02d %02d:%02d:%02d
",
    array[0] /* wYear */, array[1] /* wMonth */, array[3] /* wDay */,
    array[4] /* wHour */, array[5] /* wMinute */, array[6] /* wSecond */);
    return;
};

编译器会稍稍给出一点警告:

#!cpp
systemtime2.c(7) : warning C4133: ’function’ : incompatible types - from ’WORD [8]’ to ’LPSYSTEMTIME’

不过至少,它会产生如下代码:

清单 18.3: MSVC 2010

#!bash
$SG78573 DB ’%04d-%02d-%02d %02d:%02d:%02d’, 0aH, 00H
_array$ = -16 ; size = 16
_main PROC
    push ebp
    mov ebp, esp
    sub esp, 16 ; 00000010H
    lea eax, DWORD PTR _array$[ebp]
    push eax
    call DWORD PTR __imp__GetSystemTime@4
    movzx ecx, WORD PTR _array$[ebp+12] ; wSecond
    push ecx
    movzx edx, WORD PTR _array$[ebp+10] ; wMinute
    push edx
    movzx eax, WORD PTR _array$[ebp+8] ; wHoure
    push eax
    movzx ecx, WORD PTR _array$[ebp+6] ; wDay
    push ecx
    movzx edx, WORD PTR _array$[ebp+2] ; wMonth
    push edx
    movzx eax, WORD PTR _array$[ebp] ; wYear
    push eax
    push OFFSET $SG78573
    call _printf
    add esp, 28 ; 0000001cH
    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0
_main ENDP

当然,它也能一样正常工作! 一个很有趣的情况是这两次编译结果居然一样,所以光看编译结果,我们还看不出来到底别人用的结构体还是单单用的变量数组。 不过,没几个人会这么无聊的用这种方法写代码,因为这太麻烦了。还有,结构体也有可能会被开发者更改,交换,等等,所以还是用结构体方便。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文