c - printf() 中的格式化程序大小

标签 c printf

关于问题Why do I have to specify data type each time in C?和我之前的问题 how to read memory bytes one by one in hex(so without any format) with 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行关注的是哪些字节打印?

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

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

最佳答案

可变参数,就像在 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 and %d ALWAYS tell printf to use int format which in my pc is a 4-byte? am i right?

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

(p1+3) is a non-word aligned address Ox004+3=0x007,so what does printf() show in this case?in another way, which bytes are concerned by line 2 printf?

由于您正在打印指针值本身,因此对齐是没有意义的。不过,您不应该使用 %d 来执行此操作(如上所述)。有问题的地址可能也不是 7...我不太确定你从哪里得到的。

also, %p formatter(void *) does it need 1 byte to read(because of char)or since we talk about pointers and they always take 4 bytes(one-word)?

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

to sum up my questions, %d %x %p,.. do they read a constant size(depending on pc) from memory or it depends on what are the size of their corresponding arguments?

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

关于c - printf() 中的格式化程序大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18277831/

相关文章:

C 简单缓冲区溢出

c - printf() 中赋值运算符的问题

c++ - Lua C API 不适用于指针

c - 从函数返回结构

c++ - 检查 float 是否为负数的奇怪方法

c - printf 打印出错误的值

c++ - printf 中的 %n 是什么以及如何使用它?

c - 打印出字符时出现奇怪的前导 "f"

在C中的另一个函数中调用一个函数

c - C语言中的指针和赋值函数