鱼C论坛

 找回密码
 立即注册
查看: 1627|回复: 11

补码 ,打印结果 和位域相关的

[复制链接]
发表于 2015-7-23 19:06:00 | 显示全部楼层 |阅读模式
5鱼币
插入代码:(问题在注释里面)
  1. #include<stdio.h>
  2. #include<stdlib.h>

  3. int main(void){
  4.         int i=-3;
  5.         char str[30];
  6.        
  7.         struct bin{
  8.         char nCHAR:1;       
  9.         }use;

  10.         while(i<=3){
  11.                 use.nCHAR=i;
  12.                 itoa(use.nCHAR,str,2);
  13.                 printf("use.nCHAR=%2d ,i=%2d Bin=%s\n",use.nCHAR,i,str);
  14.                 i++;
  15.         }
  16.         return 0;
  17. }
  18. //问题:为什么(有符号数,且限制只有符号,1个bit为 1时,编译器会把补码 二进制全部打印出来?  
复制代码

运行结果

运行结果


时间:2013年7月23日19:06:54;

最佳答案

查看完整内容

编译器没那么智能 能自动打印出补码 你给他指定啥 就是啥 比如 指定%d, 那么编译器认为这个东西就是一个有符号的整形, 直接打印, 如果你制定一个字符a, 让他以%d打印出来 他直接打印一个97出来 同理 你给一个int a=97, 然后printf("%c", a), 他直接打印出一个字符a来, 占位符只会打印你指定的形式 编译器不会把补码打印出来 这个函数就是按位取, 把一个变量的内存中的每一位(补码)都取出来 然后打印出来
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-23 19:06:01 | 显示全部楼层
  1. template<typename T>
  2. void PrintComplement(T num)
  3. {
  4.         for (int i = sizeof(T)*8 - 1; i >= 0; i--)
  5.                 printf("%d", (num >> i) & 0x01);
  6. }

  7. #include<stdio.h>
  8. #include<stdlib.h>

  9. int main(void){
  10.         int i=-3;
  11.         char str[30];

  12.         struct bin{
  13.                 char nCHAR:1;        
  14.         }use;

  15.         while(i<=3){
  16.                 use.nCHAR=i;
  17.                 itoa(use.nCHAR,str,2);
  18.                 printf("use.nCHAR=%2d ,i=%2d Bin=%s\n",use.nCHAR,i,str);

  19.                 PrintComplement(use.nCHAR);
  20.                 printf("\n");

  21.                 i++;
  22.         }
  23.         return 0;
  24. }
复制代码


编译器没那么智能 能自动打印出补码
你给他指定啥 就是啥
比如 指定%d, 那么编译器认为这个东西就是一个有符号的整形, 直接打印, 如果你制定一个字符a, 让他以%d打印出来 他直接打印一个97出来
同理 你给一个int a=97, 然后printf("%c", a), 他直接打印出一个字符a来, 占位符只会打印你指定的形式 编译器不会把补码打印出来

这个函数就是按位取, 把一个变量的内存中的每一位(补码)都取出来 然后打印出来

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
lark + 1 + 1 好厉害

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-23 20:25:20 | 显示全部楼层
不懂~~~~帮顶·~~~:lol:

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
lark + 1 + 1 热爱鱼C^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-25 17:07:23 | 显示全部楼层
本帖最后由 lark 于 2015-7-25 17:11 编辑
ryxcaixia 发表于 2015-7-24 10:48
编译器没那么智能 能自动打印出补码
你给他指定啥 就是啥
比如 指定%d, 那么编译器认为这个东西就是 ...


这段代码不太懂,请问是什么意思?
我的意思是说,可以帮我加个注释吗?我理解下;
  1. void PrintComplement(T num)
  2. {
  3.         for (int i = sizeof(T)*8 - 1; i >= 0; i--)
  4.                 printf("%d", (num >> i) & 0x01);
  5. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-25 22:38:27 | 显示全部楼层
本帖最后由 ryxcaixia 于 2015-7-25 22:49 编辑
lark 发表于 2015-7-25 17:07
这段代码不太懂,请问是什么意思?
我的意思是说,可以帮我加个注释吗?我理解下;

  1. // 先不考虑模板函数
  2. // 函数功能: 打印一个整数型的补码(支持负数)
  3. void OutputComplement(int num)
  4. {
  5.         for (int i = 31; i >= 0; i--) // 一个整数是32位, 自然要循环32次, 当然更重要的是从最低位开始打印.
  6.         {
  7.                 int tmp = num >> i; // 我们想要从他的最低位开始打印, 为了获得最低位, 要将这个32位的整数右移31位, >> 这是里位移命令
  8.                                                         // 然后第二次循环就会获得他的第2位..依次类推
  9.                 tmp &= 1; // 获得到当前位后 与 1进行与操作, 取得当前位的真实数值, 因为 0 & 1 == 0, 1 & 1 == 1(如果想强制置1, 那么进行的都是或操作, 之前楼主不是经常弄int:9这样么 编译器的汇编代码就是将最低9位全部与1进行与操作)
  10.                 printf ("%d", tmp); // 然后打印出来当前的最低位

  11.                 if (i % 4 == 0)
  12.                         printf (" ");
  13.         }

  14.         printf("\n");
  15. }

  16. #include <stdio.h>

  17. int main()
  18. {
  19.         OutputComplement(10); // 这里可以看到 正 10 和 负 10 的真实补码
  20.         OutputComplement(-10);

  21.         return 0;
  22. }
复制代码


1.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-25 22:43:10 | 显示全部楼层
至于模板函数, 可以自动识别变量的类型进行绑定 更智能
楼主如果不清楚模板函数 看看c++primer的 第十六章 模板与泛型编程
简单来说 模板是通用的泛型编程 他会根据变量的类型自动实例化同类参数
举个例子

void PrintIntComplement(T num)
{
        for (int i = 32 - 1; i >= 0; i--)
                printf("%d", (num >> i) & 0x01);
}

void PrintCharComplement(T num)
{
        for (int i = 8 - 1; i >= 0; i--)
                printf("%d", (num >> i) & 0x01);
}

同样是打印补码 仅仅是某一处改变 我就要 写两个不同的函数 很麻烦
后来提出了一个叫元编程的东西 就是编译器自动帮助你“写代码”

这样我就可以把多个功能一样的函数 写在一起 不用仅仅因为某一处(多处)改变而分开写多个函数
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-26 11:58:19 | 显示全部楼层
不懂 帮忙顶
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-7-26 21:30:57 | 显示全部楼层
不懂~~~~帮顶·
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-27 16:16:27 | 显示全部楼层

Thanks:lol:
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-27 16:17:03 | 显示全部楼层

Thanks:handshake
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-27 16:18:10 | 显示全部楼层

:lol:
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-7-27 16:19:45 | 显示全部楼层
ryxcaixia 发表于 2015-7-25 22:43
至于模板函数, 可以自动识别变量的类型进行绑定 更智能
楼主如果不清楚模板函数 看看c++primer的 第十六 ...

非常感谢:handshake
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-20 18:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表