значение и отладка (печать) значения uint8_t * в c ++ - PullRequest
0 голосов
/ 28 августа 2018

Допустим, у меня есть некоторые данные (например, числа, представляющие пиксели серого изображения), которые считываются из файла и упаковываются в указатель на uint8_t.

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

Если я действительно понял, что такое указатель uint8_t, это похоже на массив беззнакового символа (отображение uint8_t на беззнаковый символ), другими словами, это указатель на первый элемент массива без знака. Это правильно?

Мои вопросы:

1) Как я могу напечатать данные значения, на которые указывает c ++?
Я читал, что в C это можно сделать так printf(*data) или printf( data[0] ). См. Распечатайте значение uint8_t *
Но как это сделать в C ++?

2) Есть ли способ итерировать (в цикле) значения данных, на которые указывают? что-то вроде:

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

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

это указатель на первый элемент массива без знака char. Это правильно?

uint8_t* - указатель на объект типа uint8_t. Если uint8_t является псевдонимом unsigned char, то uint8_t* действительно является указателем на unsigned char.

Он может указывать либо на ноль, либо на адрес, который не имеет объекта (висячий указатель), или он может указывать на объект. Мы не можем сказать, является ли этот указанный объект первым элементом массива. Если документация getData говорит, что это так, то лучшее, что мы можем сделать, это предположить, что это не ложь. Если документации нет, нам нужно увидеть реализацию, чтобы знать, что она делает.

1) Как напечатать данные значения, на которые указывает C ++?

Хотя printf доступен и в C ++, общеизвестно, что его трудно правильно использовать новичкам (на самом деле, ваши предложения не были бы правильными). Предпочтительно, вы можете вставить объект в std::cout из заголовка <iostream>, чтобы распечатать его (используя оператор вставки потока <<). Пример:

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
0 голосов
/ 28 августа 2018

Для печати на С ++ вместо 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++;
 }

UPDATE:

Если это не 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;
 }
...