-1

我正在尝试获取字节和指针以及它们的存储方式,任何人都可以解释或回答我的一些问题。谢谢

int num = 513;  <-- allocating a 4 bit memory by initializing
//[01][02][00][00] <-- (numbers are sorted and shown as litle endian)

char * ptr = &num; //char is (one byte)
   ↓
//[01][02][00][00] 
// pointer always start from the [0] (as in this array byte length) 
// in the allocated address in the memory ptr[0] is in this case = [01] 
// (printed as %x02 "printf("the byte %02x\n",ptr[0]);" - if it's only 
//single number 1 a zero will be added on the length so it prints out as 01)

int * ptr = &num; //now creating a pointer with the type of int (four bytes)
    ↓   ↓   ↓   ↓
//[01][02][00][00]
  • 我怎样才能访问这个 int 指针的第一个字节?[问题01]
  • 有没有办法查看第一个字节([01])内部的咬痕?[问题02]
  • 指针在哪里保存地址?它是否必须在 ram 中分配一个内存空间来保存地址,例如 0x233828ff21,如果是这样,这个(0x233828ff21)地址需要很多字节?[问题03]
  • 这个 int 指针在哪里存储它的类型长度(4 字节)?[问题05]
  • 如果我声明具有更长字节内存分配的类型,例如long long * ptr = &num;[01][02][00][00][00][00][00][00] 会发生什么,因为我将 long long 指向 4 字节 int ,最后这 4 个是否已经被另一个程序分配并正在使用中?我可以读吗?[问题06]
  • 二进制只有 0 和 1,其中一个(0 或 1)是否称为咬?[问题07]
  • 一个字节是8位对吗?为什么我在转换本网站(https://www.rapidtables.com/convert/number/decimal-to-binary.html)中的数字1时得到16位0000000000000001不应该是8?[问题08]
4

2 回答 2

2

注意:char * ptr = &num;确实应该unsigned char * ptr = (unsigned char *)&num;避免编译器警告并确保将字节视为无符号值。

我怎样才能访问这个 int 指针的第一个字节?[问题01]

如果你真的想访问指针的第一个字节,你可以使用:

unsigned char *ptr2 = (unsigned char *)&ptr;

然后ptr2[0]是指针的第一个字节ptr

有没有办法查看第一个字节([01])内部的咬痕?[问题02]

我假设您的意思是第一个字节内的。位不能直接寻址,因此您需要一个表达式(通常使用按位运算符)来获取每个位的值。例如,(ptr[m] >> n) & 1将是对象的第m个字节的第n位的值(其中是指向对象开头的 a)。ptrunsigned char *

指针在哪里保存地址?它是否必须在 ram 中分配一个内存空间来保存地址,例如 0x233828ff21,如果是这样,这个(0x233828ff21)地址需要很多字节?[问题03]

地址存储在指针变量中的方式与数字存储在数字类型变量中的方式相同。在 CPU 指令级别,存储的指针值和存储的整数值之间没有区别,除了宽度。

指针类型的最典型大小是 8 字节或 4 字节,具体取决于编译器的目标体系结构。

(没有问题04。)

这个 int 指针在哪里存储它的类型长度(4 字节)?[问题05]

它不存储类型的长度,但编译器知道 aTYPE *指向一个sizeof(TYPE)字节长的对象。

如果我声明一个具有更长字节内存分配的类型,例如 long long * ptr = # [01][02][00][00][00][00][00][00],会发生什么,因为我指向的是 long long 到 4 字节 int,最后 4 个是否已经被另一个程序分配并正在使用?我可以读吗?[问题06]

如果指针未针对引用的类型 ( long long) 正确对齐,则行为未定义。否则可以转换回原来的指针类型int *。在任何情况下,访问*ptr都会导致未定义的行为(除非long long宽度与 相同int,这不是典型的)。

二进制只有 0 和 1,其中一个(0 或 1)是否称为咬?[问题07]

它被称为。还有一种类型叫做_Bool. 类型表达式_Bool的值始终为 0 或 1。

一个字节是8位对吗?为什么我在转换本网站(https://www.rapidtables.com/convert/number/decimal-to-binary.html)中的数字1时得到16位0000000000000001不应该是8?[问题08]

谁在乎一些随机的网站显示什么?

C 所称的“字节”是任何为 1 的类型,sizeof(type)包括和。它至少有8 位宽,但在某些特殊系统上比 8 位宽。charsigned charunsigned char

字符类型 ( char *,signed char *unsigned char *) 的指针可用于访问任何对象中的单个字节,但对于其他大小为 1 类型的指针可能不正确,对于指向_Bool( _Bool *) 的指针当然也不正确!

于 2022-01-13T16:38:09.883 回答
1

• 如何访问这个 int 指针的第一个字节?[问题01]

通常,最好使用unsigned char而不是char访问任意字节,所以让我们这样做。

之后unsigned char *ptr = &num;ptr是指向 的指针,您可以使用orunsigned char访问 的第一个字节,如.int*ptrptr[0]printf("The first byte, in hexadecimal, is 0x%02hhx.\n", *ptr);

相反,如果您有int *ptr = &num;,则无法直接访问第一个字节。ptr这是一个指向 的指针int,并且,要访问单个字节,您需要指向一个unsigned char或其他单字节类型的指针。您可以转换ptr为指向 的指针unsigned char,就像使用 一样(unsigned char *) ptr,然后您可以使用 访问单个字节* (unsigned char *) ptr

• 有没有办法查看第一个字节([01])内部的咬痕?[问题02]

C 标准不提供显示字节的各个位的方法。通常,程序员以十六进制打印值,如上所述,并从十六进制数字中读取位。您还可以编写自己的例程从字节写入二进制输出。

• 指针将地址保存在哪里?它是否必须在 ram 中分配一个内存空间来保存地址,例如 0x233828ff21,如果是这样,这个(0x233828ff21)地址需要很多字节?[问题03]

指针是一个变量,就像你的其他变量intchar变量一样。它在内存中有自己的空间来存储它的值。(这种具有内存的变量模型用于指定 C 程序的行为。当程序被编译器优化时,它可能会改变这一点。)

在当前系统中,指针通常是 32 位或 64 位(四个或八个 8 位字节),具体取决于目标体系结构。您可以通过printf("The size of a 'char *' is %zu bytes.\n", sizeof (char *));. (C 标准允许不同类型的指针具有不同的大小,但这在现代 C 实现中很少见。)

• 这个int 指针在哪里存储它的类型长度(4 字节)?[问题05]

编译器知道指针的大小。指针本身不存储它所指向的事物的长度。当您使用指针时,编译器只会生成适当的代码。如果*ptr用来获取指针所指向的值,编译器会生成一个类型为ptris的加载字节指令,它会生成一个类型为ischar *的加载四字节指令(and is 4 bytes in你的 C 实现)。ptrint *int

• 如果我声明一个具有更长字节内存分配的类型,例如 long long * ptr = # [01][02][00][00][00][00][00][00],会发生什么,因为我指向的是long long 到 4 字节 int,最后这 4 个是否已经被另一个程序分配并正在使用?我可以读吗?[问题06]

long long是一个八字节整数,并且您有一个long long *ptr指向四字节整数时,C 标准没有定义当您尝试使用*ptr.

在通用多用户操作系统中,后面的内存int不能被另一个程序分配(除非这个程序和另一个程序都安排共享内存)。每个进程都有自己的虚拟地址空间,它们的内存是分开的。

long long *ptr在您的程序中使用它可能会访问超出int. 这可能会导致程序中出现各种类型的错误,包括数据损坏和对齐错误。

• 二进制只有0 和1,其中一个(0 或1)是否称为咬?[问题07]

一个二进制数字是一个“位”。多个二进制数字是“位”。

特定计算机作为一个单元进行操作的最小位组是“字节”。一个字节的大小可以变化;早期的计算机有不同大小的字节。现代计算机几乎都使用八位字节。

如果您的程序包含 header <limits.h>,它将定义一个名为的宏,该宏CHAR_BIT提供一个字节中的位数。在几乎所有现代 C 实现中它是 8。

• 一个字节是 8 位,对吗?为什么我在转换本网站(https://www.rapidtables.com/convert/number/decimal-to-binary.html)中的数字1时得到16位0000000000000001不应该是8?[问题08]

该网站不仅仅是转换为一个字节。

它似乎显示至少 16 位,选择 16、32 或 64 位中的最小值,该值适合作为有符号整数类型。

于 2022-01-13T16:41:23.307 回答