[英]Casting from unsigned into signed char in C
我正在使用lame
将输入raw pcm
流转换为mp3
。 该库中的编码函数返回类型为unsigned char
的数组中的mp3
编码样本。 这个mp3编码的流现在需要放在一个flv
容器中,该容器使用一个在char
数组中写入编码样本的函数。 我的问题是我将数组从lame
( unsigned char
类型)传递到flv
库。 以下代码(仅符号)说明了我的问题:
/* cast from unsigned char to char. */
#include <stdio.h>
#include <stdlib.h>
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.下面的代码中的隐式类型转换(通过将buff
传递给函数display
安全来证明吗?是否可能发生一些奇怪的行为?
2.鉴于我没有其他选择,只能坚持它们存在的功能,是否有一种“安全”的方式将unsigned char
数组转换为char
?
将unsigned char *
转换为char *
(反之亦然)的唯一问题是它应该是一个错误。 用演员表修复它。
display((char *) buff, len);
注意:此演员表是不必要的:
printf("char = %c", (char) i);
这可以:
printf("char = %c", i);
%c
格式化程序以int
arg开头,因为无论如何都不可能将char
传递给printf()
(它总是会转换为int
,或者在极不可能的情况下转换为unsigned int
。)
你似乎很担心没有必要的类型安全。 由于这是C而不是C ++,因此没有强大的打字系统。 从unsigned char
到char
转换通常是无害的,只要从未设置“符号位”即可。 避免问题的关键是真正理解它们。 C中存在以下问题/特征:
char
类型具有实现定义的signedness。 一个人不应该对其签名做任何假设,也不应该在任何类型的算术中使用它,特别是不要按比特操作。 char
应仅用于存储/打印ASCII字母。 它永远不应该与十六进制文字混合,否则可能存在微妙的错误。 char
和unsigned char
)提升为可以保存其结果的整数类型。 这实际上总是int
。 int
。 您还要转换malloc的void *结果,这在C中完全没有意义,并且在旧版本的C标准中可能有害,如果没有可见的函数原型,则将函数转换为“default int”。
然后你有各种奇怪的逻辑相关的错误和不好的做法,我已经修复但不会详细评论。 使用此修改后的代码:
#include <stdio.h>
#include <stdlib.h>
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<len; i++)
{
buff[i] = (unsigned char)ch + i;
printf("char = %c\n", buff[i]);
}
printf("\nDisplaying array in main.\n");
for(int i = 0; i < len; i++) {
printf("buff[%d] = %u\n", i, buff[i]);
}
printf("\nDisplaying array in func.\n");
display((char*)buff, len);
free(buff);
return 0;
}
C / C ++从任何整数类型转换为任何其他相同或更大的整数类型,保证不会产生数据丢失。 有符号和无符号字段之间的转换通常会产生溢出和下溢的危险,但是您转换的缓冲区实际上指向的类型实际上是无效的原始数据*。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.