现象:

先来看一段代码:

这段代码的输出结果是:

-84

4294967264

分析:

xiaoqiang@dev:~/cpp$ g++ -g c212.cc -o temp
xiaoqiang@dev:~/cpp$ ls
c143.cc c144.cc c212.cc temp

可以看到多出一个temp文件

xiaoqiang@dev:~/cpp$ gdb temp
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/xiaoqiang/cpp/temp...done.
(gdb) list
1 #include <iostream>
2
(gdb) b 6
Breakpoint 1 at 0x4007ea: file c212.cc, line 6.

3 int main(){4 unsigned u = 10;5 int i = -42;6 std::cout << i + i << std::endl;7 std::cout << u + i << std::endl;8 return 0;9 }(gdb)

进入到gdb调试模式我们来看个究竟

(gdb) b 6
Breakpoint 1 at 0x4007ea: file c212.cc, line 6.

开始运行,就会发现程序停在了第6行

(gdb) r
Starting program: /home/xiaoqiang/cpp/temp
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000 Breakpoint 1, main () at c212.cc:6
6 std::cout << i + i << std::endl;
(gdb)

我们来看看i的二进制值是多少

(gdb) print /t i
$1 = 11111111111111111111111111010110

在使用unsigned int 和 int类型变量运算的时候,首先会将int类型转换成(看成)unsigned int类型,上面两个值在内存中相加为:
11111111  11111111  11111111  01100000
十六进制为 FFFFFFE0
十进制为4294967264

练习:

看一下下面代码猜一下最终输出结果:
xiaoqiang@dev:~/cpp$ gdb temp
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/xiaoqiang/cpp/temp...done.
(gdb) list
1 #include <iostream>
2
3 int main(){
4 unsigned u1 = 42, u2 = 10;
5 std::cout << u1 - u2 << std::endl;
6 std::cout << u2 - u1 << std::endl;
7 return 0;
8 }
(gdb)

看一下u1和u2的二进制表示

Breakpoint 1, main () at c213.cc:5
5 std::cout << u1 - u2 << std::endl;
(gdb) next
32
6 std::cout << u2 - u1 << std::endl;
(gdb) next
4294967264
7 return 0;
(gdb) print /t u2
$2 = 1010
(gdb) print /t u1
$3 = 101010
(gdb)

差值为11111111  111111111  11111111  11100000

如果以unsigned int 类型显示则是 4294967264,如果以int类型显示(有符号)则为-32.

相关知识:

1、什么是GDB

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。
2、GDB的基本命令
编译时必须加上参数-g ,例:g++ -g temp.cpp -o temp.通过Gcc编译生成可执行文件才能用Gdb进行调试。进入gdb界面:gdb temp. 提示符变成(gdb)
(1)查看文件
在Gdb中键入”l”(list)就可以查看所载入的文件
(2)设置断点
只需在”b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)。如下所示:
(gdb)b 6
代码运行到第五行之前暂停(并没有运行第五行)。
(3)查看断点情况
(Gdb) info b
(4)运行代码
Gdb默认从首行开始运行代码,可键入”r”(run)即可(若想从程序中指定行开始运行,可在r后面加上行号)。
(5)查看变量值
查看断点处的相关变量值。在Gdb中只需键入”p”+变量值即可,如下所示:
(Gdb) p n
Gdb在显示变量值时都会在对应值之前加上”$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作”$N”,而无需写冗长的变量名。
(6)单步运行
使用命令”n”(next)或”s”(step),它们之间的区别在于:若有函数调用的时候,”s”会进入该函数而”n”不会进入该函数。因此,”s”就类似于VC等工具中的”step in”,”n”类似与VC等工具中的”step over”。
(7)恢复程序运行
使用命令”c”(continue).
在Gdb中,程序的运行状态有“运行”、“暂停”和“停止”三种,其中“暂停”状态为程序遇到了断点或观察点之类的,程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。故在这种状态下可以查看函数的变量值等各种属性。但在函数处于“停止”状态之后,“栈”就会自动撤销,它也就无法查看各种信息了。
(8)查看数据
print  variable        查看变量
print  *array@len      查看数组(array是数组指针,len是需要数据长度)
可以通过添加参数来设置输出格式:
/x 按十六进制格式显示变量。
 /d 按十进制格式显示变量。
/u 按十六进制格式显示无符号整型。
/o 按八进制格式显示变量。
/t 按二进制格式显示变量。 
/a 按十六进制格式显示变量。
/c 按字符格式显示变量。
/f 按浮点数格式显示变量。

一段代码的疑问(1)——unsigned与signed的更多相关文章

  1. 关于hrtimer_forward小段代码的分析【转】

    转自:http://blog.csdn.net/wowuyinglingluan/article/details/45720151 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?) ...

  2. 处理TCP连包的一小段代码

    学习网络编程也有一段时间了,一直听说TCP数据会连包,但一直不知道怎么测试好.最近测试了下:发送方使用对列,将发送的数据存入队列,然后开线程,专门发送.发送多包数据之间不延时.在接收方,他们确实连在一 ...

  3. 评《撸一段 SQL ? 还是撸一段代码? 》

    最近看到一篇博客<撸一段 SQL ? 还是撸一段代码?>,文章举例说明了一个连表查询使用程序code来写可读性可维护性更好,但是回帖意见不一致,我想作者在理论层面没有做出更好的论述,而我今 ...

  4. Unity 延迟执行一段代码的较为优雅的方式

    在Unity中,延时执行一段代码或者一个方法或者几个方法的情况非常普遍. 一般会用到Invoke和InvokeRepeating方法.顾名思义,第一个是执行一次,第二个是重复执行. 看下定义: voi ...

  5. μC/OS-Ⅲ中的临界段代码

    临界段代码(critical sections),也叫临界区(critical region),是指那些必须完整连续运行,不可被打断的代码段.μC/OS-Ⅲ系统中存在大量临界段代码.采用两种方式对临界 ...

  6. JavaScript-navigator_userAgent-编写一段代码能够区分浏览器的主流和区分

    1 userAgent:包含浏览器名称和版本号的字符串 <!DOCTYPE html> <html> <head lang="en"> < ...

  7. Python实现装饰模式的一段代码

    # 实现装饰模式的一段代码 import functools def log(func): @functools.wraps(func) def wrapper(*args,**kw): print( ...

  8. 《Focus On 3D Terrain Programming》中一段代码的注释一

    取自<Focus On 3D Terrain Programming>中的一段: //--------------------------------------------------- ...

  9. [转]Unity 延迟执行一段代码的较为优雅的方式

    Unity中,延时执行一段代码或者一个方法或者几个方法的情况非常普遍. 一般会用到Invoke和InvokeRepeating方法.顾名思义,第一个是执行一次,第二个是重复执行. 看下定义: void ...

随机推荐

  1. 将NSTimer加入至RunLoop中的两种方法差别

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  2. 当Java代码遇上抽象、重载加重写,一切都不美好了

    当Java代码遇上抽象.重载加重写.一切都不美好了 前几天调程序遇上个奇怪的bug.一直没找到问题,今天最终发现问题所在了,不说了先上代码(下面代码是演示样例代码,经測试,Java不存在这问题,安卓存 ...

  3. ubuntu-date命令的使用

    date命令是关于时间的命令.它可以用来查看.更改系统时间 它的基本格式为 date "+ %H" 注意 "+"是不可以省略的.结果如下 zhangshuli@ ...

  4. Android学习笔记进阶九之Matrix对称变换

    网上很多的倒影特效实际上就是一个对称变换,在改变透明度即可. Matrix对称变换包括很多种,有关于Y轴对称,关于X轴对称,关于y= -x对称等等. 1 关于Y轴对称 // 获取资源文件的引用res ...

  5. 10.查看npm安装信息和版本号

    转自:http://www.runoob.com/nodejs/nodejs-express-framework.html 你可以使用以下命令来查看所有全局安装的模块: $ npm list -g ├ ...

  6. dropdown下拉菜单

    <!--声明方式的下拉菜单:三个要点--> <!--1 外围容器用dropdown包裹--> <!--2 内部点击事件data-toggle--> <!--3 ...

  7. BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机/后缀自动机)

    Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣.   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...

  8. Mysql 简介二

    Mysql 数据库引擎: 数据库引擎是用于存储.处理和保护数据的核心服务 Mysql支持的引擎一般有这几种: MyISAM Mysql 5.1版本之前默认的存储引擎,仅仅支持表锁,但查询速度较Inno ...

  9. vue.js提交按钮时简单的if判断表达式示例

    简单的业务需求如下,看图说话 1:当充值金额没有填写的时候,会有Toast小弹框提示"请输入有效的充值金额" if (!this.money) { console.log('mon ...

  10. x64系统下,InpOutx64有数字签名而WinIO3.0无数字签名

    参考文档 http://www.highrez.co.uk/Downloads/InpOut32/ //可以下载InpOutx64的驱动程序及DLL,还有驱动主板硬件IO的例程 https://www ...