打印指向 uchar 值的指针
Posted
技术标签:
【中文标题】打印指向 uchar 值的指针【英文标题】:Printing pointer-to-uchar values 【发布时间】:2017-11-28 05:04:03 【问题描述】:当我在 64 位机器上运行以下代码时(编译器 clang)
typedef unsigned char byte;
void foo ( byte* a )
std::cout << sizeof(a) << std::endl;
printf( "%x\n", a );
std::cout << a << " " << a+1 << std::endl;
int main()
byte a[2];
a[0] = 'A'; a[1] = 'c';
foo( a );
return 0;
输出是
8
ea4c3a9a
Ac c
第一行是有意义的,因为这是一个 64 位指针。但是我不明白为什么第二行只有 4 个字节,或者最后一行。谁能指出第二条和第三条输出线背后的原因?
编辑:好的,那么问题是:如何正确创建以空字符结尾的字节数组,并且这样做会“正确”最后一行?
【问题讨论】:
仅供参考,编译器warn 关于printf
。
a
不是以 null 结尾的字符串,%x
不是有效的指针格式。行为未定义。
关于您的最后一个问题: 1. 提供足够的存储空间 - 例如byte a[3];
2. 在最后一个内容字节之后存储一个空终止符 - 例如a[0] = 'A'; a[1] = 'c'; a[2] = 0;
(a[2] = '\0';
也可以,但实际上也是一样的。)要分配以 null 结尾的字符串,还有一种更简单的方法:byte a[3] = "Ac";
。因此,"Ac"
被编译为 3 字节 - 空终止符被静默添加。您没有在您的 C 或 C++ 书籍中阅读所有这些内容吗?在任何一种情况下都应该提到它——可能在前 50 页的某个地方。
“但是我不明白为什么第二行只有 4 个字节”:"%x"
是unsigned
值的格式化程序。无论您在参数中输入什么 - 它都会准确读取 sizeof (unsigned)
字节并打印它们。试试sizeof (unsigned)
,你可能会得到4。(当然不是所有的64位C/C++编译器都坚持32位int
s。)格式化程序参考:printf, fprintf, sprintf, snprintf, printf_s, fprintf_s。
顺便说一句。因此printf()
函数系列被认为既强大又危险:如果您的额外参数与格式化字符串中描述的内容不完全匹配(所有这些%
序列),那么可能会发生意外的事情。因此,C++ 提供了一种类型安全的替代方案,即<<
(和>>
)运算符。顺便提一句。您是否已经决定是学习 C 还是 C++? (我会先专注于其中一个。尽管后者是从前者发展而来的,但还是有一定的差异。)
【参考方案1】:
如前所述,行为是未定义的。不过,我们可以尝试了解这里发生了什么。
第 2 行是 a 的前 4 个字节的结果。当 %x 在文字字符串中时,printf 函数需要一些无符号类型,因此将值读入无符号整数或长整数。
第 3 行只是一个 char* 的打印。虽然 a 最初是一个 c 字符串,但它被传递给函数一个 unsigned char *。您可以对其执行指针运算。
例如,如果 a 的地址是 0x1000,那么:
std::cout << a
将首先打印从 0x1000 到 '\0' 的字符,<< a + 1
部分将打印从 0x1001 到 '\0' 的字符。
幸运的是,第三个字符(不是你的,因为 a 只有 2 个字符长)可能是 '\0'。
对于您的问题,您可以非常简单地创建一个空终止字节数组。在启动时,您可以分配一个文字字符串,如下所示:
byte a[3] = "Ac";
总大小为 3,因为 '\0' 需要一个字节。
或者你可以启动它 strcpy,或者从文件 fprintf 中读取。重要的是要说第三行是空终止字节*的正确输出(它是“偶然”发生的)。如果您觉得它不正确,那么您可能正在寻找应该以不同方式编写的东西。
编辑: 既然我了解了您想要做什么(即打印 a 和 a + 1 的地址),那么您应该使用 std::cout:
#include <iostream>
int main()
unsigned char a[2];
std::cout << static_cast<void*>(a) << " " << static_cast<void*>(a + 1) << std::endl;
return 0;
输出是:
0x7ffcd22f9700 0x7ffcd22f9701
【讨论】:
>std::cout << a
将首先打印从 0x1000 到 '\0' 的字符,因此,此行为特定于 cout
,对吗?切换到printf( "%p %p\n", a, a+1 );
对我有用。以上是关于打印指向 uchar 值的指针的主要内容,如果未能解决你的问题,请参考以下文章
Arduino指向结构变量的指针和指向结构数组的指针打印输出