1

关于问题为什么我每次都必须在 C 中指定数据类型?和我之前的问题如何使用 printf() 以十六进制(所以没有任何格式)一个接一个地读取内存字节

是否可以为我澄清以下问题?

int32_t a[3]={21,3,1000031}; 
char* p1=&a[0]; /* char is 1-bye and &a[0] is 0x0004 for example */

printf("p1 in hex=%x\n",*p1); /* 4 bytes starting from word-aligned address p1 */
printf("(p1+3)=%d",(p1+3));   /* 4 bytes starting from a NON word-aligned address?* line 2 printf */
printf("p1+3=%p",p1+3) /* line 3 print*/

%x 和 %d总是告诉 printf 使用 int 格式,在我的电脑中是 4 字节?我对吗?

(p1+3) 是一个非字对齐地址 Ox004+3= 0x007,那么 printf() 在这种情况下显示什么?换句话说,第 2 行 printf 涉及哪些字节?

另外, %p formatter(void *) 是否需要 1 个字节来读取(因为 char)或者因为我们谈论指针并且它们总是占用 4 个字节(一个字)?

总结一下我的问题,%d %x %p,.. 他们是从内存中读取一个恒定大小(取决于 pc)还是取决于他们相应参数的大小?

4

2 回答 2

2

我认为您的代码没有清楚地显示您要问的内容,而是回答您的总结问题:

%d %x %p,.. 他们是从内存中读取一个常量大小(取决于 pc)还是取决于他们相应参数的大小?

他们读取的大小取决于机器上特定类型的大小。例如,对于 32 位机器,%d将读取 4 个字节,因为它假定变量是int.

我认为这段代码显示了总体思路:

int a = 1089;
printf("%c\n", a);  // prints "A" on a little-endian machine
printf("%d\n", a);  // prints "1089"
于 2013-08-16T16:33:05.450 回答
2

可变参数,就像在 C 中传递的所有其他参数一样,只是按值传递。你的案子没有任何地址。不过,在某些情况下,您正在打印指针变量的。我将尝试按顺序解释:

  1. 第一的:

    printf("p1 in hex=%x\n",*p1);
    

    将任何内容打印*p1为十六进制数字。要么 要么150具体取决于您是否分别拥有小端或大端机器。

  2. 下一个:

    printf("(p1+3)=%d",(p1+3));
    

    将尝试将任何p1 + 3内容打印为十进制数。因为p1是一个指针,所以这不是一件明智的事情,从技术上讲,这个语句会导致未定义的行为。您应该使用%p打印指针。假设您的机器上的指针和int大小相同,您可能会得到一些数字,但可能不是一个真正有意义的数字。

  3. 最后的:

    printf("p1+3=%p",p1+3)
    

    %p打印一个指针类型,所以这一行是正确的。您将(可能)获得与 #2 中相同的值,但十六进制格式除外。不过,这都是特定于机器/实现的。

至于你的其他问题:

%x并且%d总是告诉 printf 使用 int 格式,在我的电脑中是 4 字节?我对吗?

%x是为了unsigned int%d是为了int。将为您提供%x十六进制输出和%d十进制输出。如果int是您机器上的 4 字节类型,它们都会打印您传递的相应 4 字节的参数。

(p1+3)是一个非字对齐地址 Ox004+3=0x007,那么 printf() 在这种情况下会显示什么?换句话说,第 2 行 printf 涉及哪些字节?

由于您正在打印指针值本身,因此对齐毫无意义。不过,您不应该%d这样做(如上所述)。有问题的地址也可能不是7......我不确定你从哪里得到的。

此外,%pformatter( void *) 是否需要 1 个字节来读取(因为 char)或者因为我们谈论指针并且它们总是占用 4 个字节(一个字)?

%pvoid *正如您所说,必须与参数配对。它将为您的机器上的指针类型打印适当的大小(在您的情况下听起来像 4 个字节)。

总结我的问题,%d %x %p.. 他们是从内存中读取一个恒定大小(取决于 pc)还是取决于他们相应参数的大小?

他们不一定从内存中读取任何内容——这取决于您的 ABI 的工作方式以及您机器的可变参数函数的调用约定。您必须匹配格式说明符和相应变量之间的类型,否则您将导致未定义的行为。

于 2013-08-16T16:35:04.363 回答