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

时间:2013-08-16 16:17:08

标签: 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)是一个非字对齐的地址0x004 + 3 = 0x007 ,那么printf()在这种情况下显示的是什么呢?换句话说,哪些字节与第2行有关printf的?

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

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

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分: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相同的值,但十六进制格式除外。但这是所有机器/实现特定的。

  4. 关于你的其他问题:

      

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

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

      

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

    由于您自己打印指针值,因此对齐无意义。您不应该使用%d来执行此操作(如上所述)。有问题的地址可能不是7,或者......我不确定你从哪里得到它。

      

    另外,%p格式化程序(void *)是否需要1个字节来读取(因为char)或者因为我们讨论指针而且它们总是需要4个字节(单字)?

    正如您所说,

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

      

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

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