一段代码的疑问(1)——unsigned与signed

现象:

先来看一段代码:

这段代码的输出结果是:

-84

4294967264

分析:

[email protected]:~/cpp$ g++ -g c212.cc -o temp
[email protected]:~/cpp$ ls
c143.cc  c144.cc  c212.cc  temp

可以看到多出一个temp文件

[email protected]:~/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

练习:

看一下下面代码猜一下最终输出结果:

[email protected]:~/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  *[email protected]      查看数组(array是数组指针,len是需要数据长度)

可以通过添加参数来设置输出格式:

/x 按十六进制格式显示变量。

/d 按十进制格式显示变量。
/u 按十六进制格式显示无符号整型。
/o 按八进制格式显示变量。
/t 按二进制格式显示变量。 
/a 按十六进制格式显示变量。
/c 按字符格式显示变量。
/f 按浮点数格式显示变量。

一段代码的疑问(1)——unsigned与signed

时间: 2024-11-12 00:09:58

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

viewpager 自动无限循环 这段代码移到你的程序中就可以用了

本程序需要懂得viewpager的基础知识,也就是说你能够自己写出一个手动滑动的viewpager,下面我将附带加小圆点的知识 那么我们回顾一下图片轮转的基础知识,如果你已经对viewpager很熟悉了就不用看了,浪费时间 1.viewpager是在v4兼容报里面的,使用控件时请带上报名 2.数据来源用list存放,我这里用的是textview做的小圆点list<textview>,layout做的单张幻灯片list<view>,将xml文件inflate成为view,View.i

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

转自:http://blog.csdn.net/wowuyinglingluan/article/details/45720151 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 整段代码 关于无效的forward 关于定时精度问题 精确调整和overrun问题 存疑 随着各种嵌入式设备上采用linux,特别是Android系统的广泛应用,linux的hrtimer高精度模式开始被广泛支持.当然,虽说可以支持到ns精度,具体实现依赖于硬件定时器和内核编译条件,不过,一般情

有没有一段代码,让你觉得人类的智慧也可以璀璨无比?

网友在知乎的一个提问帖:有没有一段代码,让你觉得人类的智慧也可以璀璨无比?不一定要是完整算法,就是那种看着看着就觉得嗨爆了,惊为天人的结构或语句.下面是[烧茄子]引用了知名博主 Matrix67 的一篇博文:<用三段 140 字符以内的代码生成一张 1024×1024 的图片>Kyle McCormick 在 StackExchange 上发起了一个叫做 Tweetable Mathematical Art 的比赛,参赛者需要用三条推这么长的代码来生成一张图片.具体地说,参赛者需要用 C++

悠然乱弹:从一段代码讲开去

序言 今天偶然看到一框架,在框架的里面有一段这样的描述: xxx并不愿意其他人来直接修改YYY框架的代码,因为XXX致力于将它打造为完美的作品,其他人写的代码,实在没有加入进来的意义. 但是您可以当小白鼠,提意见,提bug,好的idea我还是愿意接受的. 这里解释一下,其中xxx是作者名字,YYY是框架名称,这么OSC上牛人众多,牛到这个程度的还是第一次见到,于是就想去速度学习一下.其实框架好不好,看例子代码就可以看出一二,去找了找,果然找到了示例代码,我摘了两个方法: /** * 发布文章 *

iOS测试一段代码的运行时间

王刚韧 23:19:26测试一段代码的运行时间 测试一段代码运行花了多久: NSDate* tmpStartData = [NSDate date] ;<#代码#> double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData]; NSLog(@"------cost time = %f ms(毫秒)", deltaTime*1000);

看到一段代码不明白什么意思

from warnings import filterwarnings, catch_warnings with catch_warnings():     if sys.py3kwarning:         filterwarnings("ignore", ".*mimetools has been removed",                         DeprecationWarning)     import mimetools import

从一段代码看fork()函数及其引发的竞争

首先来看一段从<UNIX环境高级编程>中摘录的一段非常有意思的代码.借此我们再来谈谈fork()函数的一些问题. #include "apue.h" static void charatatime(char*); int main(void) { pid_t pid; if((pid=fork())<0){ err_sys("fork error"); }else if(pid==0){ charatatime("output from

将PC端的网站转化成手机端网站需要增加以下这段代码即可,再布局一下界面即可

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes" /> 将PC端的网站转化成手机端网站需要增加以下这段代码即可,再布局一下界面即可,布布扣,bubuko.com

找出线上java应用中的哪段代码在大量耗费性能

from:http://chenjianjx.iteye.com/blog/1681681 你发现你的机器的cpu usage达到了100%,并且发现都是你的java应用导致的:但是,这个应用里具体哪段代码在这样吃性能呢? 以下来自一个同事的分享: 1. 先找出吃性能的线程: top -H -p pid,找出最耗性能的线程ID(最左列) 2. 获得线程ID的16进制表示: printf '0x%x\n' 线程ID 3. 然后生成一下jstack,比如 kill -3 pid 4. 在生成的jst