社区
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
...全文
474
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)
优化有问题代码完整工程
再次简化代码,取消串口,直接显示结果,仍然有问题!!
疑问代码如下:
struct _USB_DATA_STRUCT
{
/*
unsigned
char
command_data[40];//release结果正确
int command_index;
int command_size;
int numofnod;
*/
int command_index;
int command_size;
int numofnod;
unsigned
char
command_data[40];//release结果错误
void SetData(
unsigned
char
* pdata,int size)
{
if(size>40)
{
AfxMessageBox("数据太大,超范围!");
return;
}
memcpy(command_data,pdata,size);
}
};
void CTestprjDlg::OnButton1()
{
// TODO: Add your control notification handler code here
unsigned
char
ctem[32];//错误:32,103,104; 正确:105,110
USB_DATA_STRUCT CommandData;//需要填写要发送的数据
ctem[0]=0xee;
ctem[1]=0x01;
memset(ctem+2,0x00,30);
CommandData.SetData(ctem,32);
ShowTest(CommandData.command_data,32);
}
void CTestprjDlg::ShowTest(
unsigned
char
* p,int nlen)
{
CString str = _T("");
for(int i=0;i <32;i++)
{
CString tmp_str;
tmp_str.Format("0x%02X ", p[i]);
str += tmp_str;
}
m_textctrl.SetWindowText(str);
}
//VC6
Debug版本没有问题,输出如:
EE 01 00 00 00...后面全0
Release版本(按Maximize speed优化)有问题,输出如:
EE 01 00 00 00 00 00 00 00 00 00 00 EE 01 00 00 00 00 00 00 00 00 00 00 EE 01 00 00 00 00 00 00
Release版本下,按以下修改没有问题。
1.调整ctem的大小。小于等于104有问题,大于等于105没有问题。
2.将ctem改为
char
* ctem;
ctem=new
char
[32];
没有问题。
3.优化方式由Maximize speed修改为Minimize code也没问题。
请教
可能是什么原因?
c语言的
unsigned
char
,
请教
C语言程序问题,关于
unsigned
char
和
char
.
标准答案:#include #include #include #include
unsigned
char
xx[50][80];int maxline = 0; /* 文章的总行数 */int ReadDat(void);void WriteDat(void);void encrypt
Char
(){int i;
char
*pf;for(i=0;i{pf=xx[i]; //出错的地方wh...
C语言 16进制显
char
,有关
unsigned
char
*输出的有关问题(16进制)
当前位置:我的异常网» C语言»有关
unsigned
char
*输出的有关问题(16进制)有关
unsigned
char
*输出的有关问题(16进制)www.myexceptions.net网友分享于:2013-02-20浏览:195次有关
unsigned
char
*输出的问题(16进制)有一问题,
请教
各位;有一字符串集如 "010203 ",(显示结果应是16进制)
unsigned
...
请问Delphi调用VC写的dll,有传入和传出参数都是
unsigned
char
*运行中有有关问题
请教
Delphi调用VC写的dll,有传入和传出参数都是
unsigned
char
*,运行中有问题 VC写的dll的定义 extern "C "_declspec(dllexport)
unsigned
char
* GenAuthenNO(
unsigned
char
*MachineNO,
unsigned
char
*AuthenNO) Delphi
typedef struct {
unsigned
char
c : 4 ; }ss;
/* //对
请教
大师 struct {
unsigned
char
c : 4 ; } //对其意思不理解, s1.c= (s0.c<<1); */ //不大理解,请求帮助。谢谢 //检举 | 2011-9-30 09:01 提问者: 1144377120 | 浏览次数:115次 //
请教
大师 #include using namespace std; typedef struct {
C语言
69,371
社区成员
243,082
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章