C语言中无符号数和有符号数之间的运算

C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了。

unsigned int和int进行运算

直接看例子来说明问题吧

#include <iostream>
using namespace std;
int main()
{
     int a = -1;
     unsigned int b = 16;
     if(a > b)
         cout<<"负数竟然大于正数了!\n";
     return 0;
}

输出结果为:

这是因为a和b进行比较的时候,编译器将有符号数a看成了无符号数,然后再和b进行比较,在内存中(32位)

a : 11111111 11111111 11111111 11111111

b : 00000000 00000000 00000000 00010000

看成无符号数,自然是a>b。

#include <iostream>
using namespace std;
int main()
{
     int a = -1;
     unsigned int b = 16;
     cout<<a + b<<endl;
     int c = -16;
     unsigned int d = 15;
     cout<<c + d<<endl;
     return 0;
}

输出结果为:

可以看到a+b的结果貌似比较正常,但是c+d和我们想象的好像不太一样。其实4294967295就是11111111 1111111 11111111 1111111就是-1在内存中的形式,看成无符号数就是这个结果啦。所以unsigned int和int做运算会将int看成unsigned int,而且结果也是unsigned int。

unsigned char和char进行运算

看一个颠覆上面逻辑的例子:

#include <iostream>
using namespace std;
int main()
{
     char a = -16;
     unsigned char b = 14;
     if(a > b)
         cout<<"负数大于正数了!\n";
     cout<<a+b<<endl;
     return 0;
}

输出结果:

如果按照上面unsigned int和int进行运算的逻辑,这里unsigned char和char进行运算,那应该是a要看成无符号数,所以a的值比较大呀,而且a+b的结果应该是-2对应的无符号数,也就是254才对呀?

之所以会出现上面的结果是因为,C语言中比int小的整型(包括short 、unsigned short 、 unsigned char和char)在运算中都要转换成int然后进行运算。所以上面,无论是逻辑运算a>b还是算术运算a+b中a和b都默认转换成了int,所以算术运算的结果也是带符号的。

但是还需要注意一个问题就是转换成int类型的时候,高位补齐的问题。

如果是unsigned的类型转换成int类型,高位补0.

如果是signed的类型转换成int类型,如果原来最高位是1则补1,如果是0则补0。

比如:

#include <iostream>
using namespace std;
int main()
{
     char a = -16;
     unsigned char b = 255;
     char c = 255;
     cout<<a+b<<endl;
     cout<<a+c<<endl;
     return 0;
}

其中char c = 255,在内存中为11111111,最高位是1,转换成int时高位补1,也就是11111111 11111111 11111111 11111111,就是-1

注意:转换成unsigned int类型时,也是一样的。

比如:

#include <iostream>
using namespace std;
int main()
{
     char a = 255;
     unsigned int b = a;
     cout<<b<<endl;
     char c = 15;
     unsigned int d = c;
     cout<<d<<endl;
     return 0;
}

a在内存中为11111111,最高位是1,转换时高位补1,也就是

11111111 11111111 11111111 11111111,也就是无符号数2^32

c在内存中为00001111,最高位是0,转换高位补0,也就是

00000000 00000000 00000000 00001111,还是15

#include <iostream>
using namespace std;
int main()
{
     unsigned char a = 255;
     int b = a;
     cout<<b<<endl;
     unsigned char c = 15;
     int d = c;
     cout<<d<<endl;
     return 0;
}

对于unsigned char在转换成int或unsigned int时,无论最高位是0还是1,都补0。

对于unsigned short和short进行运算,和char和unsigned char一样,都是要先转换成int,然后再进行运算。

转换时高位补齐的方法也和unsigned char、char一样。

总结

以上所述是小编给大家介绍的C语言中无符号数和有符号数之间的运算,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • C语言中的强符号和弱符号介绍

    之前在extern "C" 用法详解中已经提到过符号的概念,它是编译器对变量和函数的一种标记,编译器对C和C++代码在生产符号时规则也是不一样的,符号除了本身名字的区别外,还有强符号和弱符号之分 我们先看一段简单的代码 复制代码 代码如下: /* test.c */  void hello();  int main()  {      hello();      return 0;  } 很显然,这段代码是没法链接通过的,它会报错undefined reference to hello

  • 浅谈C语言中的强符号、弱符号、强引用和弱引用

    首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样感觉的朋友交流也希望高人指点. 首先我们看一下书中关于它们的定义. 引入场景:(1)文件A中定义并初始化变量i(int i = 1), 文件B中定义并初始化变量i(int i = 2).编译链接A.B时会报错b.o:(.data+0x0): multiple definition of `i':a.o:(.d

  • 深入解读C语言中的符号常量EOF

    EOF是指文件的结束符,是一个宏定义     借助于getchar 与putchar 函数,可以在不了解其它输入/输出知识的情况下编写出 数量惊人的有用的代码.最简单的例子就是把输入一次一个字符地复制到输出,其基本思想 如下: 读一个字符 while (该字符不是文件结束指示符) 输出刚读入的字符 读下一个字符 将上述基本思想转换为C语言程序为: #include <stdio.h> /* copy input to output; 1st version */ main() { int c;

  • 举例讲解C语言链接器的符号解析机制

    1. 符号分类 (1)全局符号:非静态全局变量,非静态函数 (2)外部符号:定义于其它模块,而被本模块引用的全局变量和函数 (3)本地符号:静态变量(包括全局和局部),静态函数 对于静态局部变量,编译器会为其生成唯一的名字.如x.fun1,x.fun2.本地符号对链接器来说是不可见的. 2. 符号决议 当编译器遇到一个不是本模块定义的符号时,会假设该函数由其它模块定义,并生成一个链接器符号表条目,交由链接器处理.如果链接器在它的任何输入模块都没有找到该符号,会给出一个类似undefined re

  • 新手小心:c语言中强符号与弱符号的使用

    声明:下面的实例全部在linux下尝试,window下未尝试.有兴趣者可以试一下.文章针c初学者.c语言的强符号和弱符号是c初学者经常容易犯错的地方.而且很多时候,特别是多人配合开发的程序,它引起的问题往往非常行为怪异而且难以定位.什么是强符号和弱符号?在c语言中,函数和初始化的全局变量是强符号,未初始化的全局变量时弱符号.强符号和弱符号的定义是连接器用来处理多重定义符号的,它的规则是:不允许多个强符号:如果一个强符号和一个弱符号,这选择强符号:如果多个弱符号,则任意选一个.它的陷阱:上代码:

  • 详解C语言中的符号常量、变量与算术表达式

    C语言中的符号常量 在结束讨论温度转换程序前,我们再来看一下符号常量.在程序中使用 300.20 等类似的"幻数"并不是一个好习惯,它们几乎无法向以后阅读该程序的人提供什么信息,而且使程序的修改变得更加困难.处理这种幻数的一种方法是赋予它们有意义的名字.#define 指令可以把符号名(或称为符号常量)定义为一个特定的字符串: #define 名字 替换文本 在该定义之后,程序中出现的所有在 #define 中定义的名字(既没有用引号引起来,也不是其它名字的一部分)都将用相应的替换文本

  • C语言中无符号数和有符号数之间的运算

    C语言中有符号数和无符号数进行运算(包括逻辑运算和算术运算)默认会将有符号数看成无符号数进行运算,其中算术运算默认返回无符号数,逻辑运算当然是返回0或1了. unsigned int和int进行运算 直接看例子来说明问题吧 #include <iostream> using namespace std; int main() { int a = -1; unsigned int b = 16; if(a > b) cout<<"负数竟然大于正数了!\n";

  • C语言中使用lex统计文本文件字符数

    我曾经在Linux上写的一个C程序,借助Lex做词法分析来同时统计N个文本文件的字符数,单词数和行数.让我觉得Lex确实挺有意思的.确实Lex的功能非常强大,用来做小巧的词法分析非常适合,也非常好用.这个程序参考了<Lex与Yacc>上的一个例子. %{ unsigned int char_count = 0, word_count = 0, line_count = 0; %} %% [^ /t/n]+ {word_count++; char_count+=yyleng;}; /n {cha

  • C语言中无符号与有符号及相加问题

    C语言中无符号与有符号问题 unsigned char a[5] = { 12,36,96,128,182 }; a[]范围为0~256. 数组中数都有效. char a[5] = { 12,36,96,128,182 }; a[]范围为-128~127. 数组中128和182均无效. C语言中无符号数和有符号数相加问题 看个题: #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n"

  • 详解C语言中不同类型的数据转换规则

    不同类型数据间的混合运算与类型转换 1.自动类型转换 在C语言中,自动类型转换遵循以下规则: ①若参与运算量的类型不同,则先转换成同一类型,然后进行运算 ②转换按数据长度增加的方向进行,以保证精度不降低.如int型和long型运算时,先把int量转成long型后再进行运算 a.若两种类型的字节数不同,转换成字节数高的类型 b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型 ③所有的浮点运算都是以双精度进行的,即使是两个float单精度量运算的表达式,也要先转换成double

  • C语言详细解析有符号数与无符号数的表示

    目录 一.计算机中的符号位 二.有符号数的表示法 三.无符号数的表示法 四.signed 和 unsigned 五.小结 一.计算机中的符号位 数据类型的最高位用于标识数据的符号 最高位为1,表明这个数为负数 最高位为0,表明这个数为正数 下面看一段代码,用于判断数据的符号: #include <stdio.h> int main() { char c = -5; short s = 6; int i = -7; printf("%d\n", ( (c & 0x80

  • jsp页面中表达式语言中的$符号不起作用的解决方法

    今天myeclipse里部署了之前做的一个测试项目,发现jsp里的$符号tomcat启动后页面上显示出来了,百度搜了下别人也有类似的问题出现过.经提醒原来是web.xml配置的version设置的是2.5而我tomcat5启动的.是tomcat的版本低于web的版本,从而导致$符号不能正常使用. 后将tomcat5改用tomcat6.jdk采用1.6 启动spring2.5项目.$显示问题解决. 以下是网上摘录的详细说明: 在jsp页面中用表达式语言中的$符号,如${pageScope.titl

  • 详解R语言中的表达式、数学公式、特殊符号

      在R语言的绘图函数中,如果文本参数是合法的R语言表达式,那么这个表达式就被用Tex类似的规则进行文本格式化. y <- function(x) (exp(-(x^2)/2))/sqrt(2*pi) plot(y, -5, 5, main = expression(f(x) == frac(1,sqrt(2*pi))*e^(-frac(x^2,2))), lwd = 3, col = "blue") library(ggplot2) x <- seq(0, 2*pi, b

  • C语言中弱符号与弱引用的实际应用

    最近在学习<程序员的自我修养--链接.装载与库>时,get到了一个新的知识点:弱符号与弱引用.书中简短的介绍,让我了解到弱符号的含义以及使用方式.了解我的朋友,应该知道我喜欢将知识点与我们实际工作结合起来,在工作中利用起来,正所谓学以善用.根据我的理解,觉得利用弱符号的特性可以帮组我们在工作中编写出更加稳定,可复用,可组合的优秀代码.在此向大家分享. 符号重定义错误 在编码过程中,我们经常遇到符号重定义的错误.编译器会报如下错误: multiple definition of `xxx'; 这

  • 关于C语言中弱符号与弱引用的实际应用问题

    最近在学习<程序员的自我修养--链接.装载与库>时,get到了一个新的知识点:弱符号与弱引用.书中简短的介绍,让我了解到弱符号的含义以及使用方式.了解我的朋友,应该知道我喜欢将知识点与我们实际工作结合起来,在工作中利用起来,正所谓学以善用.根据我的理解,觉得利用弱符号的特性可以帮组我们在工作中编写出更加稳定,可复用,可组合的优秀代码.在此向大家分享. 符号重定义错误 在编码过程中,我们经常遇到符号重定义的错误.编译器会报如下错误: multiple definition of `xxx'; 这

随机推荐