今天在
imageData[i*widthStep+j])<=127)
image->imageData[i*widthStep+j]=0;
发线所有的值都变为了0,而且,跟踪发现imageData出现负值。
原来是
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。
不带signed或unsigned关键字的char型 无符号数? 有符号数? C标准规定为 Implementation Defined(由实作环境决定)。
arm-linux-gcc 规定 char 为 unsigned char 。
gcc规定为signed char
以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int ,这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
为了代码移植,一定不要用 char !
我以前总以为 char 代表有符号,而 unsigned char 代表无符号。现在才知道如果换做 short 或 int , 这样理解都没问题,因为c标准明确定义了。但是,唯独 char 不能这样理解,因为c标准中对此是 Impementation Defined,就是未明确定义,由具体的编译器明确定义。
vc编译器、x86上的 gcc 都把 char 定义为 signed char;而 arm-linux-gcc 却把 char 定义为 unsigned char 。这样一来,在代码移植上就会出现问题。举个最简单的例子:
char a = 0xb6; if ( a == 0xb6) puts("hello world !");
在vc 或 x86的gcc 上,都是不会打印出 hello world! 的。用 arm-linux-gcc 编译,在arm板上,是可以打印出hello world ! 的。是不是很神奇啊???<wbr>我们再变化一下:<br><br>
char a = 0xb6;<br>
short b = 0xb600;<br>
int c = 0xb6000000;<br><br>
if ( a == 0xb6) puts("a");<br>
if ( b == 0xb600) puts("b");<br>
if ( c == 0xb6000000) puts("c");<br><br>
在vc 或 x86的gcc 上,只会打印出 c 。用 arm-linux-gcc 编译,在arm板上,是可以打印出 a 和 c 。是不是发现了什么了呢?<br><br>
首先,介绍 Integer Promotion 。通俗点说,c在处理整型(char short int)时,都会自动提升为int(如果int范围不够,则提升成 unsigned int)。比如<wbr>“a == 0xb6”,首先0xb6会当一个int来处理,变为0x000000b6(关于常量,后面还会仔细说明)。a 会提升为int ,假如 char 被定义为有符合的,那么 a 为负数,因为最高位为1,所以 a会提升为 0xffffffb6。假如 char 被定义为无符号的,那么a会提升为 0x000000b6
。<br><br>
即,在vc 或 x86的gcc 上,a == 0xb6 会变为 0xffffffb6 == 0x000000b6 ,而在 arm-linux-gcc 上,变为 0x000000b6 == 0x000000b6。<br><br>
对于 short,因为c标准明确规定 不加关键字,就代表有符号数。所以,无论在什么编译器上 b == 0xb600 都会变成 0xffffb600 == 0x0000b600 。<br><br>
对于 int,本身是int,也就不用 Integer Promotion 了,所以<wbr>c == 0xb60000 中 ,c不做任何处理,直接从内存中读出来,即<wbr>0xb60000 == 0xb60000。<br><br>
最后,简单说一下常量。我后面会转帖一部分资料,有兴趣可以看看,我现在只说用八进制(0开头)或十六进制(0x开头)表示的常量,他们都会当成无符号数处理!另外像 char a = 0xb6; 这句就有两个 Implementation Defined,一个是char带不带符号,另外一个是,假如char为有符合, 0xb6 会当int 0x000000b6 处理,把这个int 变为 有符合的 char 有溢出,会有问题,0xb6本为正数,赋值到a中却变为负数,具体要怎么处理,c对此也是 Implementation
Defined。<br><div>
<div>
<div>
<div><wbr>扩展阅读:<a href="http://learn.akae.cn/media/ch15s01.html" style="text-decoration:none; color:rgb(62,115,160)">http://learn.akae.cn/media/ch15s01.html</a></wbr></div>
</div>
</div>
</div>
</wbr></wbr></wbr></wbr>
分享到:
相关推荐
opencv中的iplimage格式图像与一般unsigned char*型的bmp图像转换,同时也解决了坐标的问题
OPENCV下针对IplImage实现图像增强处理
由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构。IplImage结构来源于Intel的另外一个函数库Intel Image Processing Library (IPL),该函数库主要是针对图像处理。...
OpenCV计算IplImage类型图像灰度均值
在c++buidler 10.2 中使用TBitmap显示OpenCV中的IplImage图片,用做视觉识别
OpenCV将GIF转为IplImage的解决方法 源代码
FreeImage图像库是一个开源图像库,能够帮助我们快速实现图像的读取与转换操作,由于大部分做图像处理的人接触的比较多的还是OpenCV,这里给出一个通用的图像格式转为IplImage格式的代码实现。
利用opencv进行IplImage类型提取原始
可以让OpenCV的IplImage指向的图像显示在C#的窗体上,当然也可以显示在C#的PictureBox上了.这是一个示例程序.
opencv中Mat、CvMat、IplImage、IplImage*数据类型之间转换方法
public static BufferedImage iplToBufImgData(IplImage ipl,BufferedImage image ) public static IplImage BufImgToIplData(IplImage ipl,BufferedImage bi)
该类可以在MFC中绑定一个static控件,从而将该控件作为OpenCV的IplImage图像显示控件。该类不仅可以以1:1、全窗口、半窗口、动态选择等方式显示IplImage图像,还可以对图像进行平移、放缩,并在信息区同步显示图像...
减少openCv打开rtsp摄像头延时问题
把kinect的图片数据转移到opencv的iplimage结果上去显示。
opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接opencv图片拼接...
主要解决在配置OpenCV时遇到问题的解决办法,删除配置的变量。
opencv3和opencv4多线程内存泄漏问题:以cv::resize函数测试结果为例。 使用中可修复或者可避免内存泄漏:1)使用opencv2的版本;2)在代码中设置修复该问题.
本代码基于VS2010,重写了静态文本框控件显示OpenCV数据,解决了GetDlgItem(ID)获得控件句柄的存在不属于对话框类的问题。提供了IplImage和Mat类的数据接口,方便好用,还可以继续开发。
OpenCV 是一个广受欢迎的开源计算机视觉库,它
编译opencv4.5.4 出现opencv_videoio_ffmpeg_64 下载失败 后程序运行MP4写入失败 [ INFO:0] global F:\opencv\opencv\sources\modules\videoio\src\videoio_registry.cpp (223) cv::`anonymous-namespace'::...