unsigned char 与 char 有啥却别?何时适用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unsigned char 与 char 有啥却别?何时适用相关的知识,希望对你有一定的参考价值。

一、在C中,默认的基础数据类型均为signed,如定义变量为int,long等,都为有符号的。如果要定义无符号类型,必须显式地在变量类型前加unsigned。

二、char与unsigned char 

1、相同点:在内存中都是一个字节,8位(2^8=256),都能表示256个数字 

2、不同点:char的最高位为符号位,因此char能表示的数据范围是-128~127,unsigned char没有符号位,因此能表示的数据范围是0~255

3、实际使用中,如普通的赋值,读写文件和网络字节流都没有区别,不管最高位是什么,最终的读取结果都一样,在屏幕上面的显示可能不一样。

扩展资料:

1、但是要把一个char类型的变量赋值给int、long等数据类型或进行类似的强制类型转换时时,系统会进行类型扩展,这时区别就大了。对于char类型的变量,系统会认为最高位为符号位,然后对最高位进行扩展,即符号扩展。

2、若最高位为1,则扩展到int时高位都以1填充。对于unsigned char类型的变量,系统会直接进行无符号扩展,即0扩展。扩展的高位都以0填充。所以在进行类似的操作时,如果char和unsigned char最高位都是0,则结果是一样的,若char最高位为1,则结果会大相径庭。

3、char*是有符号的,如果大于127即0x7F的数就是负数了,使用%x格式化输出,系统自动进行了符号扩展,就会产生变化。

4、所以在涉及到类型提升的上下文中,要注意使用char*和unsinged char*的区别。

参考资料来源:百度百科--unsigned char

参考技术A 本质上两种类型都占一个字节。
作为字符使用时,都是存储字符的ASCII码。比如:
unsigned char uc='a';
char c='a';
printf("%d %d",uc,c);
结果为: a a
作为整数使用时,两种类型的取值范围就不同了。unsigned char 可取0至255,而char可取-128至+127。比如:
unsigned char uc=255;
char c=255;
printf("%d %d",uc,c);
结果为: 255 -1
原因是没有用unsigned修饰的char类型系统将其存储的一个字节值(8位2进制)看作为一个有符号数来处理,最高位为0时,表示正数,为1时表示负数,表示负数时的值为余下7位二进制每一位取反后整体+1。
比如上例中:char c=255; 表面看来超过了char的范围,但系统并不是这样处理的。
系统将十进制数255转为二进制数11111111进行存储。在计算或打印时,发现最高位为1,是负数,余下7位1111111取反后为0000000,加1后为0000001,转为十进制数等于1,最后系统当作-1看待。所以此时按整数打印c时,输出为-1。
总的来说,系统最终存储的都是二进制数11111111,只是在参与运算或显示的时候,unsigned char和char才会有所区别。
参考技术B 对于英文字符来说char就够了
但是对于很多双字节的语音,需要两个char来表示一个字
第一个char的值就会大于127,需要unsigned char来表示,或者是负值的char
参考技术C unsigned char为有符号8位数,-128到+127
char为无符号8位数,,0-255

正则表达式 (.*) .* 就是这2种写法,有啥却别?分别代表啥含义?

正则表达式正则表达式正则表达式正则表达式正则表达式正则表达式
(.*)
.*
这2种写法,有什么却别?分别代表什么含义?

把正则表达式的一部分放在圆括号内,你可以将它们形成“组”,表达式的处理引擎会把括号内的处理结果记下来,并给他编号(分别为\1,\2...)。然后你可以对这个结果(即“组”)使用一些正则操作,例如重复操作符。

事实上,当用“()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。当对被匹配的组进行向后引用的时候,可以用“\数字”的方式进行引用。<<\1>>引用第一个匹配的后向引用组,<<\2>>引用第二个组,以此类推,<<\n>>引用第n个组。而<<\0>>则引用整个被匹配的正则表达式本身。
可能有点抽象,我们看一个例子。

假设你想匹配一个HTML标签的开始标签和结束标签,以及标签中间的文本。比如<B>This is a test</B>,我们要匹配<B>和</B>以及中间的文字。我们可以用如下正则表达式:“<([A-Z][A-Z0-9]*)[^>]*>.*?</\1>”

首先,“<”将会匹配“<B>”的第一个字符“<”。然后[A-Z]匹配B,[A-Z0-9]*将会匹配0到多次字母数字,后面紧接着0到多个非“>”的字符。最后正则表达式的“>”将会匹配“<B>”的“>”。接下来正则引擎将对结束标签之前的字符进行惰性匹配,直到遇到一个“</”符号。然后正则表达式中的“\1”表示对前面匹配的组“([A-Z][A-Z0-9]*)”进行引用,在本例中,被引用的是标签名“B”。所以需要被匹配的结尾标签为“</B>”

你可以对相同的后向引用组进行多次引用,<<([a-c])x\1x\1>>将匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用数字形式引用的组没有有效的匹配,则引用到的内容简单的为空。

一个后向引用不能用于它自身。<<([abc]\1)>>是错误的。因此你不能将<<\0>>用于一个正则表达式匹配本身,它只能用于替换操作中。

后向引用不能用于字符集内部。<<(a)[\1b]>>中的<<\1>>并不表示后向引用。在字符集内部,<<\1>>可以被解释为八进制形式的转码。

向后引用会降低引擎的速度,因为它需要存储匹配的组。如果你不需要向后引用,你可以告诉引擎对某个组不存储。例如:<<Get(?:Value)>>。其中“(”后面紧跟的“?:”会告诉引擎对于组(Value),不存储匹配的值以供后向引用。
参考技术A .* 代表的是通配符
外边有括号的和不写括号区别在于括号的用法
在正则表达式中 ()表示模式单元
当()的正则式匹配时 可以通过调用模式单元的方法调用匹配的内容
用//1 这种格式 调用追问

用//1 这种格式 调用 不太名表啊
可以加你QQ咱们聊聊吗?

追答

qq:250578663

本回答被提问者采纳
参考技术B 前者捕获括号里的内容 后者不捕获。如果能达到同样的效果建议后者,效率稍高。
正则里尽量少写. 比如用[^>]之类的代替点号
如果知道字符串长度范围 比如 捕获微博内容 部分就用 [^>]0,160

总之,尽可能减少回溯次数。

参考资料:http://829621.boaiaa.com/

参考技术C (.*) 可以在后面引用或取值 group(1) 取值或\1引用追问

.*呢?

追答

group(0)表示整个匹配的内部,无法引用

以上是关于unsigned char 与 char 有啥却别?何时适用的主要内容,如果未能解决你的问题,请参考以下文章

std::string 与 unsigned char[] 和 unsigned char* 有啥不同?

有啥方法可以从 iOS 的 plist 加载 const unsigned char 吗?

unsigned char 与unsigned long互换

char和unsigned char--数据类型区别

用unsigned char 表示字节

关于unsigned char 型数据转换成十进制或者16进制的问题