p.apply("Read new file", TextIO.read()
.from("gs://my_bucket/*")
.withCompression(Compression.GZIP)
.watchForNewFiles(Duration.standardMinutes(1), Watch.Growth.never()))
此代码的输出为:
#include<stdio.h>
int main()
{ int i;
int *p;
p = &i;
i=5;
printf("i = %d, p = %P, *p = %d\n",i,p,*p);
*p=6;
printf("i = %d, p = %P, *p = %d\n",i,p,*p);
return 0;
}
在第一条语句和第二条语句中应将* p = 5赋予* p = 6
答案 0 :(得分:4)
在您的printf中,您尝试显示p = %P
或%P
不存在,因此%
P将被忽略并且将像字符串一样打印。
此后,当您尝试打印*p = %d
时,不打印变量*p
,而是打印p
,因为p
未被{ {1}}。
正确的printf应该是:
%P
答案 1 :(得分:4)
您已将以下字符串指定为printf()
的格式字符串:
i = %d, p = %P, *p = %d
然后您指定要打印的三个元素:
i, p, *p
因此,%d
被替换为i
中存储的值,符合预期:
i = 5, p = %P, *p = %d
到目前为止一切正常,除了一件事:%P
格式不存在。因此,它会被跳过作为说明符,而是打印出来。
然后将第二个%d
替换为p
中的值,不 *p
,因为第二个%d
是下一个有效的说明符,而p
是下一个要使用的变量:
i = 5, p = %P, *p = -1009882308
由于没有更多说明符可供使用,*p
被忽略,并且在编译时会引发警告或错误。
恭喜,您刚刚将p
指向的地址打印为int
,也就是未定义的行为。
那么,我们该如何解决?
将%P
替换为实际的有效说明符:%p
。现在,使用了所有变量和说明符,您的代码将平稳运行。
这是printf()
应该打印的内容:
i = 5, p = C3CE6B3C, *p = 5
注意:使用%p
打印p
的地址,该地址将以十六进制数字显示。
编辑:如 chux 所述,%p
需要相应的void*
才能正常工作。在p
语句中将(void*)
强制转换为printf()
,如下所示:(void*)p
答案 2 :(得分:2)
您的格式说明符有错字,无法识别。结果,您传递了要打印为整数的指针。应该是这样的:
printf("i = %d, p = %p, *p = %d\n",i,p,*p);
大多数编译器都会为您的代码发出警告。如果不是,请检查是否可以通过警告更严格地更改设置。
答案 3 :(得分:1)
为什么下面的C代码的输出是这样的?
是的,我的编译器警告%P,但如果我们不关注%P,则还要警告* p,它应返回值i,即5和6 comment。
关键问题是假设警告后的代码表现良好。
该警告是由于使用无效的打印说明符"%P"
导致的。这会导致不确定的行为(UB)。其余代码不再具有任何指定的行为。因此,C不支持“应该返回值,即5,然后是6”。输出可能是任何东西。
使用有效的打印说明符和匹配的参数。
使用"%p"
打印void*
。要将p
转换为void*
,请进行强制转换。
// printf("i = %d, p = %P, *p = %d\n",i,p,*p);
printf("i = %d, p = %p, *p = %d\n", i, (void*)p, *p);
答案 4 :(得分:0)
%P
不是有效的转换说明符,因此您的第二个参数p
使用%d
打印为十进制整数,而*p
则根本不打印。
将两行都更改为
printf("i = %d, p = %p, *p = %d\n",i, (void *)p,*p);
^
|
+---- note lower case p here
,您将获得期望的输出。