18.1 SYSTEMTIME 的例子

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

清单18.1: WinBase.h

  1. typedef struct _SYSTEMTIME {
  2. WORD wYear;
  3. WORD wMonth;
  4. WORD wDayOfWeek;
  5. WORD wDay;
  6. WORD wHour;
  7. WORD wMinute;
  8. WORD wSecond;
  9. WORD wMilliseconds;
  10. } SYSTEMTIME, *PSYSTEMTIME;

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

  1. #include <windows.h>
  2. #include <stdio.h>
  3. void main()
  4. {
  5. SYSTEMTIME t;
  6. GetSystemTime(&t);
  7. printf ("%04d-%02d-%02d %02d:%02d:%02d",
  8. t.wYear, t.wMonth, t.wDay,
  9. t.wHour, t.wMinute, t.wSecond);
  10. return;
  11. };

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

清单18.2: MSVC 2010

  1. _t$ = -16 ; size = 16
  2. _main PROC
  3. push ebp
  4. mov ebp, esp
  5. sub esp, 16 ; 00000010H
  6. lea eax, DWORD PTR _t$[ebp]
  7. push eax
  8. call DWORD PTR __imp__GetSystemTime@4
  9. movzx ecx, WORD PTR _t$[ebp+12] ; wSecond
  10. push ecx
  11. movzx edx, WORD PTR _t$[ebp+10] ; wMinute
  12. push edx
  13. movzx eax, WORD PTR _t$[ebp+8] ; wHour
  14. push eax
  15. movzx ecx, WORD PTR _t$[ebp+6] ; wDay
  16. push ecx
  17. movzx edx, WORD PTR _t$[ebp+2] ; wMonth
  18. push edx
  19. movzx eax, WORD PTR _t$[ebp] ; wYear
  20. push eax
  21. push OFFSET $SG78811 ; ’%04d-%02d-%02d %02d:%02d:%02d’, 0aH, 00H
  22. call _printf
  23. add esp, 28 ; 0000001cH
  24. xor eax, eax
  25. mov esp, ebp
  26. pop ebp
  27. ret 0
  28. _main ENDP

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

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

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

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

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

清单18.3: MSVC 2010

  1. $SG78573 DB ’%04d-%02d-%02d %02d:%02d:%02d’, 0aH, 00H
  2. _array$ = -16 ; size = 16
  3. _main PROC
  4. push ebp
  5. mov ebp, esp
  6. sub esp, 16 ; 00000010H
  7. lea eax, DWORD PTR _array$[ebp]
  8. push eax
  9. call DWORD PTR __imp__GetSystemTime@4
  10. movzx ecx, WORD PTR _array$[ebp+12] ; wSecond
  11. push ecx
  12. movzx edx, WORD PTR _array$[ebp+10] ; wMinute
  13. push edx
  14. movzx eax, WORD PTR _array$[ebp+8] ; wHoure
  15. push eax
  16. movzx ecx, WORD PTR _array$[ebp+6] ; wDay
  17. push ecx
  18. movzx edx, WORD PTR _array$[ebp+2] ; wMonth
  19. push edx
  20. movzx eax, WORD PTR _array$[ebp] ; wYear
  21. push eax
  22. push OFFSET $SG78573
  23. call _printf
  24. add esp, 28 ; 0000001cH
  25. xor eax, eax
  26. mov esp, ebp
  27. pop ebp
  28. ret 0
  29. _main ENDP

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