Кастинг от неподписанного в символ со знаком в C

Я преобразовываю вход сырье pcm , поток в mp3 использующий хромой . Функция кодирования в той библиотеке прибыль mp3 закодированные образцы во множестве типа неподписанная случайная работа . Этот mp3-закодированный поток теперь должен быть помещен в flv контейнер, который использует функцию, которая пишет закодированные образцы в случайная работа множество. Моя проблема состоит в том, что я передаю множество из , хромого (типа неподписанная случайная работа ) в flv библиотека. Следующая часть кода (только символический) иллюстрирует мою проблему:

/* cast from unsigned char to char. */

#include 
#include 

void display(char *buff, int len) {

  int i = 0;
  for(i = 0; i < len; i++) {
    printf("buff[%d] = %c\n", i, buff[i]);
  }
}

int main() {

  int len = 10;
  unsigned char* buff = (unsigned char*) malloc(len * sizeof(unsigned char));
  int i = 0;

  for(i = 65; i < (len + 65); i++) {
    buff[i] = (unsigned char) i;
    printf("char = %c", (char) i);
  }

  printf("Displaying array in main.\n");
  for(i = 0; i < len; i++) {
    printf("buff[%d] = %u\n", i, 'buff[i]');
  }

  printf("Displaying array in func.\n");
  display(buff, len);

  return 0;
}

Мой вопрос (вопросы):
1. Неявное преобразование типов в коде ниже (как продемонстрировано, встречая любителя в функцию показ безопасный? Некоторое странное поведение, вероятно, произойдет?
2. Учитывая, что у меня есть мало выбора, но придерживаться функций, как они присутствуют, - там "безопасный" способ преобразовать множество неподписанная случайная работа s в случайная работа s?

2
nl ja de

4 ответы

Единственная проблема с преобразованием неподписанная случайная работа * в , который случайная работа * (или наоборот) - то, что это предполагаемых , чтобы быть ошибкой. Зафиксируйте его с броском.

display((char *) buff, len);

Note: This cast is unnecessary:

printf("char = %c", (char) i);

Это прекрасно:

printf("char = %c", i);

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

5
добавлено

Вы, кажется, волнуетесь много о безопасности типов, где нет никакой потребности в ней. Так как это - C и не C++, там не существует никакая система строгого контроля типов. Преобразования из , неподписанная случайная работа , чтобы случайную работу является обычно безопасный, пока "знаковый бит", никогда не устанавливаются. Ключ к предотвращению проблем должен на самом деле понять их. Следующие проблемы/особенности существуют в C:

  • дефолт случайная работа тип определил внедрением signedness. Никогда не нужно делать предположения о его signedness, ни использовать его в арифметике любого вида, особенно не битовые операции. случайная работа должен только использоваться для хранения/печати писем о ASCII. Это никогда не должно смешиваться с шестнадцатеричными опечатками или есть потенциал для тонких ошибок.
  • продвижения целого числа в C неявно продвигают все маленькие целые типы, среди них случайная работа и неподписанная случайная работа , к целому типу, который может держать их результат. Это на практике всегда будет интервал .
  • Официально, преобразования указателя между различными типами могли быть неопределенным поведением. Но преобразования указателя между неподписанной случайной работой и случайной работой на практике безопасны.
  • опечатки Характера '\0' и т.д. имеет тип интервал в C.
  • printf и подобный дефолт функций продвигают все параметры характера интервал

Вы также бросаете пустоту* результат malloc, который абсолютно бессмыслен в C и потенциально вреден в более старых версиях стандарта C, который перевел функции к "интервалу по умолчанию", если никакой прототип функции не был видим.

И затем у вас есть различные странные связанные с логикой ошибки и плохая практика, которую я зафиксировал, но не прокомментирую подробно. Используйте этот измененный код:

#include 
#include 

void display(const char *buff, int len) {

  for(int i = 0; i < len; i++) {
    printf("buff[%d] = %c\n", i, buff[i]);
  }
}

int main() {

  int len = 10;
  unsigned char* buff = malloc(len * sizeof(unsigned char));

  if(buff == NULL)
  {
   //error handling
  }

  char ch = 'A';
  for(int i=0; i
3
добавлено
Нет никакой интерпретации, связанной с битовыми операциями, особенно никакой signedness. В чем проблема, например, с c & 0xdf как toupper?
добавлено автор Rainald62, источник
О, Ясно. Есть "только теоретическая" проблема.
добавлено автор Rainald62, источник

Вы, кажется, волнуетесь много о безопасности типов, где нет никакой потребности в ней. Так как это - C и не C++, там не существует никакая система строгого контроля типов. Преобразования из , неподписанная случайная работа , чтобы случайную работу является обычно безопасный, пока "знаковый бит", никогда не устанавливаются. Ключ к предотвращению проблем должен на самом деле понять их. Следующие проблемы/особенности существуют в C:

  • дефолт случайная работа тип определил внедрением signedness. Никогда не нужно делать предположения о его signedness, ни использовать его в арифметике любого вида, особенно не битовые операции. случайная работа должен только использоваться для хранения/печати писем о ASCII. Это никогда не должно смешиваться с шестнадцатеричными опечатками или есть потенциал для тонких ошибок.
  • продвижения целого числа в C неявно продвигают все маленькие целые типы, среди них случайная работа и неподписанная случайная работа , к целому типу, который может держать их результат. Это на практике всегда будет интервал .
  • Официально, преобразования указателя между различными типами могли быть неопределенным поведением. Но преобразования указателя между неподписанной случайной работой и случайной работой на практике безопасны.
  • опечатки Характера '\0' и т.д. имеет тип интервал в C.
  • printf и подобный дефолт функций продвигают все параметры характера интервал

Вы также бросаете пустоту* результат malloc, который абсолютно бессмыслен в C и потенциально вреден в более старых версиях стандарта C, который перевел функции к "интервалу по умолчанию", если никакой прототип функции не был видим.

И затем у вас есть различные странные связанные с логикой ошибки и плохая практика, которую я зафиксировал, но не прокомментирую подробно. Используйте этот измененный код:

#include 
#include 

void display(const char *buff, int len) {

  for(int i = 0; i < len; i++) {
    printf("buff[%d] = %c\n", i, buff[i]);
  }
}

int main() {

  int len = 10;
  unsigned char* buff = malloc(len * sizeof(unsigned char));

  if(buff == NULL)
  {
   //error handling
  }

  char ch = 'A';
  for(int i=0; i
3
добавлено
Нет никакой интерпретации, связанной с битовыми операциями, особенно никакой signedness. В чем проблема, например, с c & 0xdf как toupper?
добавлено автор Rainald62, источник
О, Ясно. Есть "только теоретическая" проблема.
добавлено автор Rainald62, источник

Броски C/C++ от любого целочисленного типа до любого другого same-larger целочисленного типа, как гарантируют, не произведут потерю данных. Броски между подписанными и неподписанными областями обычно создавали бы переполнение и опасности подземного глубинного потока, но буфер, вы преобразовываете на самом деле пункты в необработанные данные, тип которых действительно void*.

1
добавлено