【发布时间】:2016-05-26 18:48:39
【问题描述】:
我的书试图让我熟悉一些概念,例如关于结构的指针取消引用和一些访问结构的奇怪方法。我是新手,发现下面的代码令人困惑。
#include <stdio.h>
#include <time.h>
void dump_time_struct_bytes(struct tm *time_ptr, int size) {
int i;
unsigned char *raw_ptr;
printf("bytes of struct located at 0x%08x\n", time_ptr);
raw_ptr = (unsigned char *)time_ptr;
for (i = 0; i < size; i++)
{
printf("%02x ", raw_ptr[i]);
if (i % 16 == 15) // Print a newline every 16 bytes.
printf("\n");
}
printf("\n");
}
int main() {
long int seconds_since_epoch;
struct tm current_time, *time_ptr;
int hour, minute, second, i, *int_ptr;
seconds_since_epoch = time(0); // Pass time a null pointer as argument.
printf("time() - seconds since epoch: %ld\n", seconds_since_epoch);
time_ptr = ¤t_time; // Set time_ptr to the address of
// the current_time struct.
localtime_r(&seconds_since_epoch, time_ptr);
// Three different ways to access struct elements:
hour = current_time.tm_hour; // Direct access
minute = time_ptr->tm_min; // Access via pointer
second = *((int *)time_ptr); // Hacky pointer access
printf("Current time is: %02d:%02d:%02d\n", hour, minute, second);
dump_time_struct_bytes(time_ptr, sizeof(struct tm));
minute = hour = 0; // Clear out minute and hour.
int_ptr = (int *)time_ptr;
for (i = 0; i < 3; i++) {
printf("int_ptr @ 0x%08x : %d\n", int_ptr, *int_ptr);
int_ptr++; // Adding 1 to int_ptr adds 4 to the address,
} // since an int is 4 bytes in size.
}
输出:
time() - seconds since epoch: 1189311744
Current time is: 04:22:24
bytes of struct located at 0xbffff7f0
18 00 00 00 16 00 00 00 04 00 00 00 09 00 00 00
08 00 00 00 6b 00 00 00 00 00 00 00 fb 00 00 00
00 00 00 00 00 00 00 00 28 a0 04 08
int_ptr @ 0xbffff7f0 : 24
int_ptr @ 0xbffff7f4 : 22
int_ptr @ 0xbffff7f8 : 4
-
我。我知道作者已将 *time_ptr 重新声明为指向 unsigned char 的指针,但它是如何成为数组(我认为是字符数组)的?我认为这可能与数组被解释为指向它们的第 0 个元素的指针有关,但我不确定。
二。其次,dump_time_struct_bytes 函数的输出(转储的字节)是什么?我知道那是结构中的字节,但我不知道它们应该如何构成存储在其中的 4 小时、22 分钟和 24 秒(如果是这样的话)。还有,*time_ptr的地址对应什么?它是结构的开始吗?如果后者为真,那么输出中对应的转储字节是只属于其第一个元素(tm_sec)还是属于整个结构?
对“hacky 指针”的解释有点奇怪 - 为什么取消引用转换后的整数指针只会显示结构中第一个元素的内容 - tm_sec?
提前谢谢你。
【问题讨论】:
-
ii.在不提醒自己
struct tm成员的情况下,我可以从printf("%02x ", raw_ptr[i]);制作的十六进制转储中看到,前 12 个字节是三个 32 位整数,小端格式,因为 hex 18 = dec 24(秒),hex 16 = 12 月 22 日(分钟),4 是小时。 -
感谢您的回答。然而,有一件事似乎有点不清楚。假设我有一个指向 char 'c' 的指针。指针现在是指向大小为 1 的 char 数组的指针吗?此外,为了验证,您已经提到指向单个结构的指针是指向大小为 1 的数组的指针。因此,将该指针类型转换为指向 char 的指针将导致数组大小现在大于 1 并且是字节数组,负责十六进制转储。因此,任何指针在以这种方式进行类型转换时是否会导致这种良好的字节分解?
-
你可以索引一个指针就像它是一个数组。 C 在这里没有限制。即使您定义了一个指向 single
char变量的指针,您也可以完全按照您的意愿进行索引,以防止读/写被禁止的内存,或者在写入不'不会导致 direct 错误,但会在一段时间后产生问题 ;-) (这就是为什么指针错误很难追踪的原因)。在这里,char*指针是从struct地址转换而来的,因此可以逐字节检查其内容。