c++中uint8_t*值的含义和调试(打印)

Posted

技术标签:

【中文标题】c++中uint8_t*值的含义和调试(打印)【英文标题】:meaning and debuging (print) of uint8_t* value in c++ 【发布时间】:2018-08-28 12:50:16 【问题描述】:

假设我有一些数据(例如代表灰度图像像素的数字)从文件中读取并打包到指向 uint8_t 的指针中。

uint8_t* data = getData(readFile(filePath));

如果我真正理解了什么是 uint8_t 指针,它就像一个 unsigned char 数组(uint8_t 映射到 unsigned char),换句话说,它是一个指向 unsigned char 数组第一个元素的指针。它是否正确?

我的问题是:

1) 如何在 c++ 中打印值数据点? 我在C 中读到它可以像这样printf(*data)printf( data[0] )。见Print out the value uint8_t * 但是如何在 C++ 中做到这一点?

2) 有没有办法迭代(在循环中)指向的值数据点? 类似:

for(auto i=0; i< data.size; i++) 
   auto d = data[i]; 

【问题讨论】:

data 指向的数据是否指向一个以空字符结尾的字节串?而且你显然认为它可以用 C 打印的方式也是错误的。 另外,指针是指向某个位置的指针,仅此而已。没有与指针关联的数据的大小或长度的概念。如果你有一个指向第一个元素的指针,并且需要遍历一组连续的元素,那么你需要从某个地方显式地获取大小。 在读取文件功能中,您还应该跟踪从文件中读取的字节数。假设您将字节数存储在 cnt 变量中,您可以编写一个循环,如 for (size_t i = 0; i &lt; cnt; i++) data[i]; @Someprogrammerdude 关于它是如何在 C 中完成的我没有尝试过,但根据 ***.com/questions/31937276/… 应该是这样的 printf(data[0])printf("%d", data[0])非常不同 【参考方案1】:

它是指向 unsigned char 数组的第一个元素的指针。它是否正确?

uint8_t* 是指向uint8_t 类型对象的指针。如果uint8_tunsigned char 的别名,那么uint8_t* 确实是指向unsigned char 的指针。

它既可以指向空值,也可以指向一个没有对象的地址(悬空指针),也可以指向一个对象。那个指向的对象是否是数组的第一个元素,我们不可能说。如果getData 的文档说它是,那么我们能做的最好的就是假设它没有说谎。如果没有文档,那么我们需要查看实现以了解它的作用。

1) 如何在 c++ 中打印值数据点?

虽然printf 在 C++ 中也可用,但众所周知,初学者很难正确使用它(事实上,您的建议并不正确)。最好将对象从&lt;iostream&gt; 标头插入std::cout 以打印它(使用流插入运算符&lt;&lt;)。示例:

std::cout << data[0];

但是,如果uint8_t 确实是unsigned char 的别名,那么数据将作为字符流式传输。如果要流式传输整数值,则需要先将值转换为非字符整数类型:

std::cout << int(data[0]);

要打印数组等数据结构,可以遍历数组并打印每个元素,

2) 有没有办法迭代(在循环中)值数据点到?

是的。

然而,为了迭代一个数组,你需要知道什么时候停止迭代。这与知道数组的结束位置相同。这也是getData 的文档应该揭示的东西。数组是否具有恒定长度?数组是否被某个值终止?它是否设置了一些全局变量来为我们提供数组的长度?也许;我们不知道。

您可以使用以下算法:

1 let the pointer point to the first element of the array
2 if the pointer points to the end of the array, you're done
3 indirect the pointer to get the value at current index
4 you you can now for example print the value
5 increment the pointer
6 jump to 2

【讨论】:

【参考方案2】:

要在 c++ 中打印而不是 printf("%d", data[0] ) 使用 std::cout &lt;&lt; data[0];,而不是 printf("%d", *data ) 使用 std::cout &lt;&lt; *data;

注意,std::cout &lt;&lt; 根据数据类型进行格式化,如果你想改变一些东西,你需要更多:例如#include &lt;iomanip&gt;.

此外,当您使用指针时(在 C 或 C++ 中无关紧要),您不应该在指针有效之前访问数据。至少检查data != NULL,然后在表达式中使用*data

而且最重要的是 - 如果data 是像uint8_t* data; 这样的指针,它没有属性(字段)data.size,所以循环应该以其他方式组织。我的意思是,你必须找到其他方法来知道该指针有多少数据可用......例如:

 size_t size = ... // calculate the length of array before loop
 for (size_t cnt = 0; cnt < size; cnt++) 
      std::cout << data[cnt];
 

或者如果数组末尾由特殊值定义,则可以是:

 uint8_t* ptr = data;
 while ( *ptr != END_MARKER ) 
      std::cout << *ptr;
      ptr++;
 

更新:

如果不是uint8_t*,而是类似于队列结构的东西

typedef struct
   uint8_t    data;
   QueueItem* next;
 QueueItem;

NULL指针本身可以是END_MARKER,例如:

 QueueItem* ptr = queue;
 while ( ptr != NULL ) 
      std::cout << ptr->data;
      ptr = ptr->next;
 

【讨论】:

虽然在技术上是正确的,但真正打印的可能不是 OP 想要打印的。这实际上取决于数据及其代表的内容。 @Someprogrammerdude 完全正确。数据是数字。像灰度图像的像素值 @Gaetan 然后你不能像字符一样打印它(这是打印单个 uint8_t 值会做的)。您需要将其转换为整数。 @Someprogrammerdude 不管打印什么类型,我只想看到所有的值。但是当我做 cout @Gaetan 你可能对cout 如何与char* 指针一起工作感到困惑。它异常地将其视为指向字符数组的指针并将它们全部打印出来,直到找到空终止符。其他指针类型不会发生这种情况。从根本上说,问题是没有办法知道从指向第一个元素的指针到数组中有多少元素。它仅适用于char*,因为空终止符表示结束。

以上是关于c++中uint8_t*值的含义和调试(打印)的主要内容,如果未能解决你的问题,请参考以下文章

Boost Asio error_code 的错误值的含义

C ++将mac id字符串转换为uint8_t数组

VS2012 如何在输出窗口中打印调试信息 C++语言

如何在 C# 中存储从 C++ 函数返回的 uint8_t* 变量?

android ndk调试C++ 代码怎么打印异常信息?

在 C++ 中从 size_t 转换/转换为 uint8_t?