最近在做一个C的嵌入式项目,发现在C语言中用printf()函数打印字符型变量时,如果想采用"%x"的格式将字符型变量值以十六进制形式打印出来,会出现一个小问题,如下:

  1. char buf[10] = {0};
  2. buf[0] = 0xbf;
  3. printf("%2x\n\n\n", buf[0]);            /*在终端将会显示成:ffffffbf*/
  4. buf[1] = 0x7f;
  5. printf("%2x\n\n\n", buf[1]);            /*在终端将会显示成:7f*/

为什么buf[0]不像buf[1]显示的那样,显示2个十六进制数bf呢?

研究发现,只要字符型变量值的二进制第一位是1,就会如buf[0]所显示的那样,出现6个f。

而格式输出函数printf中会对所输出的变量做有符号/无符号型的判断。如果是有符号型变量,且该值二进制首位为1(如我们定义的是char buf[100],且buf[0]中为0xbf),则会按照补码形式前面全置为1,也就是全为f。(因为终端显示的是8个十六机制数字;另外,我用Tobor C编译,因为Tobor C中int是2bytes,终端显示就成4个十六进制数字了:ffbf,因此我猜测,printf函数显示之前先将有符号型值转换成了一个4bytes的int。当然,这是函数内部的处理,跟我们所说的话题关系不大。)。

按照上面述说的,如果把buf声明为unsigned char型,则显示会变成:bf

而且,如果程序需要讲一个有符号型的变量以十六进制形式输出,且只显示两位,可以强制类型转换为无符号型变量,如上面的buf[0],可以转换成:(unsigned char)buf[0]

此外,如果有人这样来测试这个问题,

  1. printf("%2x\n\n\n", 0xbf);               /*在终端将会显示成:bf*/

为什么这边没有6个f呢?因为,printf()函数第二个参数直接以int型来接收,int型变量4bytes,二进制首位自然为0,因此不会显示多个f。

原文http://guhanjie.iteye.com/blog/1765585

(转)C语言16进制输出字符型变量问题的更多相关文章

  1. C语言中以十六进制输出字符型变量会出现'ffffff"的问题

    最近在做一个C的嵌入式项目,发现在C语言中用printf()函数打印字符型变量时,如果想采用"%x"的格式将字符型变量值以十六进制形式打印出来,会出现一个小问题,如下: char  ...

  2. 基于visual Studio2013解决面试题之1203转16进制输出

     题目

  3. C printf按8进制、10进制、16进制输出以及高位补0

    ; /*按整型输出,默认右对齐*/ printf("%d\n",PrintVal); /*按整型输出,补齐4位的宽度,补齐位为空格,默认右对齐*/ printf("%4d ...

  4. python - 2 8 16进制/颜色/字符编码

    1.二进制 八进制 十六进制 二进制: bin() 0b10010八进制: oct() 0o10十进制: 1-100十六进制: hex() 0X53 BH 十进制转2, 8,16进制: >> ...

  5. C语言 16进制与ascii码互转

    /*把ASCII字符转换为16进制 */ uint8_t char_to_hex(const uint8_t *ch) { uint8_t value = 0; if(*ch >= 0 & ...

  6. Go -- socket read的内容以16进制输出

    buf := make([]) reqLen, err := conn.Read(buf) // 遍历, 转为16进制 buffer := new(bytes.Buffer) for _, b := ...

  7. C语言各种进制输出

    #include<stdio.h> int main() { ; float f = 12.0; printf("十进制输出:%d\n", number); print ...

  8. byte数组转16进制 输出到文件

    try { File file = new File(Environment.getExternalStorageDirectory(),"shuju2"); if(!file.e ...

  9. C语言 16进制转float

    float hex_to_float(uint8_t *data) { float num = 0.0; uint8_t dd[4] = {data[0], data[1], data[2], dat ...

随机推荐

  1. java -json()

    json-lib和org.json的使用几乎是相同的,我总结出的区别有两点: 两种包 1. List集合转换成json方法 List list = new ArrayList(); list.add( ...

  2. linux 学习15 16 启动管理,备份和恢复

    第十五讲 启动管理 . CentOS .x 启动管理 //此处指6.3 系统运行级别 .运行级别 运行级别 含 义 关机 单用户模式,可以想象为windows的安全模式,主要用于系统修复 //linu ...

  3. linux学习 联网

    /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0ONBOOT=yesBOOTPROTO=staticIPADDR=192.168.199.** ...

  4. table变色

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  5. [转]Android音频底层调试-基于tinyalsa

    http://blog.csdn.net/kangear/article/details/38139669 [-] 编译tinyalsa配套工具 查看当前系统的声卡 tinymix查看混响器 使用ti ...

  6. jQuery:提交表单前判断表单是否被修改过

    表单加载完成后执行 : //表单中包含input(text,checkbox,hidden),select,radio,   $("#editWithdrawAutoApprovedConf ...

  7. (转)UIWebView全部API学习

    网上找的收藏一下 http://www.myexception.cn/web/1888974.html 最生僻的API做了下划线以及粗体的标注.百度上查了全是拷贝的同一份代码,而且只有代码没有解释,很 ...

  8. Android Dex文件格式(二)

    第三块: 数据区         索引区中的最终数据偏移以及文件头中描述的map_off偏移都指向数据区, 还包括了即将要解析的class_def_item, 这个结构非常重要,下面就开始解析   c ...

  9. [整理]Matlab之中心平滑滤波

    滑动平均(moving average):在地球物理异常图上,选定某一尺寸的窗口,将窗口内的所有异常值做算术平均,将平均值作为窗口中心点的异常值.按点距或线距移动窗口,重复此平均方法,直到对整幅图完成 ...

  10. GridLayout自定义数字键盘(两个EditText)

    功能说明: 适用于两个EditText输入框,并控制输入字符的长度,点击键盘中的"确定"按钮完成输入,点击"前一项"光标跳到前一个EditText 运行效果图如 ...