社区
C语言
帖子详情
一个很简单的char 与unsigned char 区别,请教一下大家
laiguo
2011-08-16 06:51:01
int main(int argc, char* argv)
{
char buf[4]= {0};
*(buf+2) = (char)0xDD;
printf("it is %x \n", *(buf+2));
return 0;
}
输出为it is ffffffdd
改为
unsigned char buf[4]= {0};
后输出就是对了,
it is dd
...全文
578
21
打赏
收藏
一个很简单的char 与unsigned char 区别,请教一下大家
int main(int argc, char* argv) { char buf[4]= {0}; *(buf+2) = (char)0xDD; printf("it is %x \n", *(buf+2)); return 0; } 输出为it is ffffffdd 改为 unsigned char buf[4]= {0}; 后输出就是对了, it is dd
复制链接
扫一扫
分享
举报
写回复
配置赞助广告
用AI写文章
21 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
辰岡墨竹
2011-08-19
打赏
举报
回复
[Quote=引用 18 楼 laiguo 的回复:]
buf+3的那个字节确实是被重写了,你不信可以自己试一下,你可以不输出你写文件试一下,就知道那个字节的内容变了,
[/Quote]
我试了一下,printf("%x", *(buf+3));
没有啊,buf+3确实没有改变啊。
我承认的确有地方误解了你的说法,但是其实问题的重点在于。你要求输出一个hex,因为你的变量是char型的,所以printf就得按signed char,在前面加了ffffff,这个符号扩展一定要有的,否则就不能表明是signed了。注意%x定义其输出结果就是Unsigned hexadecimal integer,如果直接输出a0,就是000000a0了。
举个例子,我让某个变量是-1,结果它被显示成1,那肯定是转换错误,必须有一种方式表示出负号来。比如fffffff,这样才是正确的。
注意它只是printf在显示时做的处理,并不是给你增加了3个字节。所以你只是看起来增加了宽度。
辰岡墨竹
2011-08-19
打赏
举报
回复
[Quote=引用 15 楼 frankhb1989 的回复:]
引用 3 楼 i_code 的回复:
和机器相关。某些机器char就等于unsigned char。换而言之就是在某些机器上它们没有区别。
错误。C/C++的char/signed char/unsigned char是三种不同的类型。
只不过算术运算的行为char可以类似signed char也可以类似unsigned char。
[/Quote]
你才是错误的,C/C++里char只有两种signed char或unsigned char。C标准没有规定必须那个,不过由于UNIX下最早的C实现用的signed char,所以一般的编译器都默认是signed的。但是一般都提供一个编译参数设置char为unsigned。
laiguo
2011-08-17
打赏
举报
回复
[Quote=引用 14 楼 bokutake 的回复:]
你怎么知道buf +3被修改了呢?你单独只用%d打印一下那个*(buf+3)看看。0xA0正好是位于GBK编码空间里的东西。所以输出时将buf+2和buf+3被作为一个汉字来解释。其实buf+3的值没有改变。
你可以先在程序最前面system("chcp 437");
就不会显示汉字了。
[/Quote]
buf+3的那个字节确实是被重写了,你不信可以自己试一下,你可以不输出你写文件试一下,就知道那个字节的内容变了,
laiguo
2011-08-17
打赏
举报
回复
[Quote=引用 16 楼 bokutake 的回复:]
对,12楼说的也很对,你这个代码另一个问题是明显有访问违规。虽然你已经从堆里new一块数组空间,但是buf = "abcdefgk";这个相当于把buf的指针又指向了一个字符串常量。
之后你尝试修改常量内容,你肯定用的是TC吧,在更为严格的编译器里,必定报告内存错误,因为字符串常量是不应该被修改的。
C语言没有内置字符串类型,所以要复制字符串内容,应该用strcpy(buf, "abcdef……
[/Quote]
我只是想说明那个内存里面我放了什么,才那样赋的,而且你没有明白我的意思
辰岡墨竹
2011-08-17
打赏
举报
回复
对,12楼说的也很对,你这个代码另一个问题是明显有访问违规。虽然你已经从堆里new一块数组空间,但是buf = "abcdefgk";这个相当于把buf的指针又指向了一个字符串常量。
之后你尝试修改常量内容,你肯定用的是TC吧,在更为严格的编译器里,必定报告内存错误,因为字符串常量是不应该被修改的。
C语言没有内置字符串类型,所以要复制字符串内容,应该用strcpy(buf, "abcdefgk");
直接修改buf指针还会导致你之前new的空间没有指针指向,就无法delete释放其空间,产生内存泄漏。
FrankHB1989
2011-08-17
打赏
举报
回复
[Quote=引用 3 楼 i_code 的回复:]
和机器相关。某些机器char就等于unsigned char。换而言之就是在某些机器上它们没有区别。
[/Quote]
错误。C/C++的char/signed char/unsigned char是三种不同的类型。
只不过算术运算的行为char可以类似signed char也可以类似unsigned char。
辰岡墨竹
2011-08-17
打赏
举报
回复
你怎么知道buf +3被修改了呢?你单独只用%d打印一下那个*(buf+3)看看。0xA0正好是位于GBK编码空间里的东西。所以输出时将buf+2和buf+3被作为一个汉字来解释。其实buf+3的值没有改变。
你可以先在程序最前面system("chcp 437");
就不会显示汉字了。
tangxianghenggood
2011-08-17
打赏
举报
回复
讨论的很激烈,要的就是这种犀利啊
jldream110
2011-08-16
打赏
举报
回复
顶6楼 不重复了
stein42
2011-08-16
打赏
举报
回复
char *buf = new char[20];
buf = "abcdefgk";
*(buf+2) = (char)0xA0;
这段代码通常会出现段错误,还有内存泄漏。
汉字是用多个字节表示的,所以输出的汉字由几个字节决定。
laiguo
2011-08-16
打赏
举报
回复
[Quote=引用 10 楼 liu111qiang88 的回复:]
引用 8 楼 laiguo 的回复:
引用 6 楼 babilife 的回复:
首先要了解一下范围
unsigned char 0~255
char -128~127
所以当你
char buf[4]= {0};时候
是0xdd=221已经超出了原始范围,所以你用单步执行的时候会看到是-35
为什么是-35呢,我们来看一下负数在内存中的表示方法补码:
即:反码+1
……
[/Quote]
看我写的7楼的红字,
火头军
2011-08-16
打赏
举报
回复
[Quote=引用 8 楼 laiguo 的回复:]
引用 6 楼 babilife 的回复:
首先要了解一下范围
unsigned char 0~255
char -128~127
所以当你
char buf[4]= {0};时候
是0xdd=221已经超出了原始范围,所以你用单步执行的时候会看到是-35
为什么是-35呢,我们来看一下负数在内存中的表示方法补码:
即:反码+1
1101 1101(221)
0010……
[/Quote]
%x 默认为整形打印的为 32为 所以 当为负数是自动扩展符号 1
laiguo
2011-08-16
打赏
举报
回复
[Quote=引用 7 楼 supermegaboy 的回复:]
引用 4 楼 laiguo 的回复:
引用 2 楼 yq_118 的回复:
char可以是有符号的,
0xDD传给它就转化为是一个负数,
调用printf时再提升为int类型,还是负数,
按16进制打印出来就是那样了。
事实是我存进去的就是一个INT型的数据,我想知道更深层次原因
char与unsigned char两者是有很大区别的,使用者很容易被两者相同的1字节……
[/Quote]
非常谢谢,讲的很好。
不过你理解错的我意思了,
我不需要保证我的存的数据是
数值
,我只是向里面存入数据,
例如:
char *buf = new char[20];
buf = "abcdefgk";
*(buf+2) = (char)0xA0;
读出来整个字符为“
it is ab燿efgk
”
也就是buf+2 和buf +3的数据都被改写了,我想知道为什么.
如果正常的话,只有第三个字节是被改写为
oxA0
的
laiguo
2011-08-16
打赏
举报
回复
[Quote=引用 6 楼 babilife 的回复:]
首先要了解一下范围
unsigned char 0~255
char -128~127
所以当你
char buf[4]= {0};时候
是0xdd=221已经超出了原始范围,所以你用单步执行的时候会看到是-35
为什么是-35呢,我们来看一下负数在内存中的表示方法补码:
即:反码+1
1101 1101(221)
0010 0010(反码)
……
[/Quote]
我是想知道前面的那三个字节是到底怎么出来的
飞天御剑流
2011-08-16
打赏
举报
回复
[Quote=引用 4 楼 laiguo 的回复:]
引用 2 楼 yq_118 的回复:
char可以是有符号的,
0xDD传给它就转化为是一个负数,
调用printf时再提升为int类型,还是负数,
按16进制打印出来就是那样了。
事实是我存进去的就是一个INT型的数据,我想知道更深层次原因
[/Quote]
char与unsigned char两者是有很大区别的,使用者很容易被两者相同的1字节二进制宽度所迷惑,以为它们是一回事,事实上两者用途完全不一样。
signed char和unsigned char是用于数值的,两者用于1字节的整数类型数值表示,而char并非用于数值表示,而是用于字符的,这就是为什么虽然有signed char和unsigned char却仍然存在char的原因。
char是实现相关的,底层类型可以是signed char和unsigned char中的一种,不过,无论哪种底层类型,都必须保证执行字符集中的字符码值必须是正的,码值的范围随1字节的位数而定,绝大多数情况的8位字节下是0到127,超出此范围的属于扩展字符集,C/C++标准不保证符号为正。
因此,如果你希望使用1字节的整数类型,不要使用char,应使用signed char或者unsigned char。
对于楼主的代码,结果随char的实现而变,如果底层类型为signed char(大多数情况),由于0xDD在signed char中为负数,因此打印的时候进行符号扩展成为ffffffdd,如果底层类型为unsigned char,则为DD。
至善者善之敌
2011-08-16
打赏
举报
回复
首先要了解一下范围
unsigned char 0~255
char -128~127
所以当你
char buf[4]= {0};时候
是0xdd=221已经超出了原始范围,所以你用单步执行的时候会看到是-35
为什么是-35呢,我们来看一下负数在内存中的表示方法补码:
即:反码+1
1101 1101(221)
0010 0010(反码)
+ 1
————————
0010 0011 (十六进制为-23)
然而负数显示出来的时候即又为反码加+
ff ff ff DD
laiguo
2011-08-16
打赏
举报
回复
[Quote=引用 3 楼 i_code 的回复:]
和机器相关。某些机器char就等于unsigned char。换而言之就是在某些机器上它们没有区别。
[/Quote]
这个是在PC上的
laiguo
2011-08-16
打赏
举报
回复
[Quote=引用 2 楼 yq_118 的回复:]
char可以是有符号的,
0xDD传给它就转化为是一个负数,
调用printf时再提升为int类型,还是负数,
按16进制打印出来就是那样了。
[/Quote]
事实是我存进去的就是一个INT型的数据,我想知道更深层次原因
I_code
2011-08-16
打赏
举报
回复
和机器相关。某些机器char就等于unsigned char。换而言之就是在某些机器上它们没有区别。
stein42
2011-08-16
打赏
举报
回复
char可以是有符号的,
0xDD传给它就转化为是一个负数,
调用printf时再提升为int类型,还是负数,
按16进制打印出来就是那样了。
加载更多回复(1)
谈谈
unsigned
char
,short,int ,long的位长
原文:http://www.cnblogs.com/yqskj/articles/2229480.html 最近经常见到这些
unsigned
char
,short,int ,long的定义,有时真的不确定位长是多少 ,上网查,又话是跟编译器有关,没
一个
准确答案。于是只好自己找答案,其实用
一个
最简 单地方就可以知道其长度,就是用sizeof函数。于是我写了如下一段:
用memset给
一个
char
设置0xff,然后将该
char
和0xff ==,能相等么?
#include<stdio.h> #include<string.h> intmain() {
char
a; memset(&a,0xff,1); if(a==0xff) printf("Equal.\n"); ...
NFDATA定义的
一个
细节
#defineNFDATA(*(volatile
unsigned
long*)0x4E000010) #defineNFDATA(*(volatile
unsigned
char
*)0x4E000010) 对于有些寄存器,可能这两种定义基本上等价的. 我当时也是这么觉得的 ...
关于符号扩展的问题
#include int main(void) {
char
test = 0xf1; printf("
char
:%02x\n", test); printf("
unsigned
char
:%02x\n", (
unsigned
char
)test); return 0; } x
嵌入式课程设计——温控器
用DS18B20做的。亮点在于它采用one-wire 总线进行传输数据。调试的时候,温度到了16度以后,再高就变成8度了。我们检查了两个小时也没能找出问题。最后
请教
高人才知道:数据的解释权在其上执行的操作手中。为了对字节操作,我们的变量都是定义成
char
型。
char
表现为8个bit(谁知道VC 是不是用32位来实现的?!),但与
char
相关的操作并不当它是
一个
byte。这才造成了这种
C语言
70,040
社区成员
243,245
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章