关于问题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)还是取决于它们对应参数的大小是什么?
答案 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中传递的所有其他参数一样,仅是按值传递。在你的情况下,没有任何地址发生。但在某些情况下,您正在打印指针变量的值。我会尝试按顺序解释:
首先:
printf("p1 in hex=%x\n",*p1);
将*p1
作为十六进制数打印。这可能是15
或0
,具体取决于您是分别使用小端还是大端机。
下一步:
printf("(p1+3)=%d",(p1+3));
将尝试打印p1 + 3
作为十进制数字的任何内容。由于p1
是一个指针,这不是一个理智的事情,从技术上讲,这个语句会导致未定义的行为。您应该使用%p
来打印指针。假设指针和int
在你的机器上大小相同,你可能会获得一些数字,但可能不是真正有意义的数字。
最后:
printf("p1+3=%p",p1+3)
%p
打印指针类型,因此该行正确。您将(可能)获得与#2相同的值,但十六进制格式除外。但这是所有机器/实现特定的。
关于你的其他问题:
%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如何工作以及您的机器可变参数的调用约定。您必须匹配格式说明符和相应变量之间的类型,否则您将导致未定义的行为。