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 < cnt; i++) data[i];
@Someprogrammerdude 关于它是如何在 C 中完成的我没有尝试过,但根据 ***.com/questions/31937276/… 应该是这样的
printf(data[0])
与printf("%d", data[0])
非常不同
【参考方案1】:
它是指向 unsigned char 数组的第一个元素的指针。它是否正确?
uint8_t*
是指向uint8_t
类型对象的指针。如果uint8_t
是unsigned char
的别名,那么uint8_t*
确实是指向unsigned char
的指针。
它既可以指向空值,也可以指向一个没有对象的地址(悬空指针),也可以指向一个对象。那个指向的对象是否是数组的第一个元素,我们不可能说。如果getData
的文档说它是,那么我们能做的最好的就是假设它没有说谎。如果没有文档,那么我们需要查看实现以了解它的作用。
1) 如何在 c++ 中打印值数据点?
虽然printf
在 C++ 中也可用,但众所周知,初学者很难正确使用它(事实上,您的建议并不正确)。最好将对象从<iostream>
标头插入std::cout
以打印它(使用流插入运算符<<
)。示例:
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 << data[0];
,而不是 printf("%d", *data )
使用 std::cout << *data;
注意,std::cout <<
根据数据类型进行格式化,如果你想改变一些东西,你需要更多:例如#include <iomanip>
.
此外,当您使用指针时(在 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*值的含义和调试(打印)的主要内容,如果未能解决你的问题,请参考以下文章