C语言中变量的类型变换比较多,有些地方需要时刻注意,不然很可能写出带有bug的代码并深埋入系统,难以察觉。

例如 有符号类型和无符号类型运算,有符号类型转换为无符号类型。

需要注意的有两种情况:
1、有符号和无符号的算术运算
2、有符号和无符号的比较运算

一、验证有符号类型转换为无符号类型:
程序:
#include <stdio.h>

int main()
{
int a = -20;
unsigned int b = 6;

if((a+b) > 0)
{
printf("signed to unsigned\n");
}
else
{
printf("unsigned to signed\n");
}

return 0;
}

结果为:
signed to unsigned

这说明在c语言操作中,如果遇到无符号数与有符号数之间的操作,编译器会自动转化为无符号数来进行处理。
这个也验证了有符号和无符号算术运算操作时会将有符号类型转换为无符号类型来计算。

二、比较运算

#include <stdio.h>

int main()
{
int a = -2;
unsigned int b = 1;

printf("a = %d, b = %u\n\n", a, b);

if(a > b)
{
printf("a > b\n");
}
else
{
printf("a < b\n");
}

return 0;
}
结果:
a > b

这说明有符号数和无符号数进行比较运算时(==,<,>,<=,>=),有符号数隐式转换成了无符号数(即底层的补码不变,但是此数从有符号数变成了无符号数),此时的a的值远大于b。

=============

C中有符号数与无符号数转化之间的危险

无符号数与有符号数之间存在着很多细节问题,稍有不慎就可能导致程序出现不可预料的错误。

陷阱

在C语言中,如果一个运算包含一个有符号数和一个无符号数,那么C语言会隐式地将有符号数转换为无符号数,这对于标准的算术运算没什么问题,但是对于 < 和 > 这样的关系运算符来说,它会出现非直观的结果,这种非直观的特性经常会导致程序中难以察觉的错误

看下面的例子:
int strlonger(char *s, char *t)
{
return strlen(s) - strlen(t) > 0;
}

上面的函数看起来似乎没什么问题, 实际上当s比t短时,函数的返回值也是1, 为什么会出现这种情况呢?

原来strlen的返回值类型为size_t,C语言中将size_t定义为unsigned int,当s比t短时,strlen(s) - strlen(t)为负数,但无符号数的运算结果隐式转换为无符号数就变成了很大的无符号数.

为了让函数正确工作,代码应该修改如下 :
return strlen(s) > strlen(t);

2002年, 从事FreeBSD开源操作系统项目的程序员意识到,他们对getpeername函数的实现存在安全漏洞.代码的简化版本如下:
//void *memcpy(void *dest, void *src, size_t n);

#define KSIZE 1024
char kbuf[KSIZE];

int copy_from_kernel(void *user_dest, int maxlen)
{
int len = KSIZE < maxlen ? KSIZE : maxlen;
memcpy(user_dest, kbuf, len);
retn len;
}

你看出了问题所在吗?

=========

测试时一些细节地方会影响结果,需要注意

1、测试的时候需要注意printf的输出参数对结果的影响:
#include <stdio.h>

int main()
{
unsigned int a = 1;
signed int b = -2;

printf("%d\n", a + b);
printf("%u\n", a + b);

return 0;
}

printf("%d\n", a + b)中,由于%d的作用,使a+b以有符号十进制的形式输出,此时,最高位的1为符号位,减一取反得到其原码,得到1000 0001,即十进制的-1;

printf("%u\n", a + b)中,由于%u的作用,使a+b以无符号十进制的形式输出,此时,最高位的1并非符号位,其表示数值大小,不用减一取反,得到1111 1111,实际Linux系统中,该数用4个字节表示,也就是说实际上这里有16个"1",即十进制数的4294967295(=2^32-1)。

综上,该段程序的输出结果为:

-1

4294967295

2、不要使用char类型来验证这个规则,会使分析变得复杂

一方面是因为char类型在不同编译器环境下可能是无符号的,也可能是有符号的,取决于编译器的实现。
【这个可以搜索“char可以是负数吗”来了解。】

另一方面char类型在运算的时候会提升为int类型再运算,这会导致结果分析极其繁琐,结果不同不代表无符号和有符号这个运算规则有错。

C语言 有符号类型转换为无符号类型相关推荐

  1. 负数转换为无符号数据类型的理解及应用

    负数转换为无符号类型数据的理解及应用 负数转换为无符号数据类型的理解及应用 有符号整型和无符号整型的转换 有符号类型和无符号类型的转换应用实例 参考文献 负数转换为无符号数据类型的理解及应用 网上有大 ...

  2. C语言有符号整型和无符号整型的比较

    int s = -1; unsigned int u = 1; if(s < u) 这样比较的结果是:s>u,即出现-1>1 因为:在有符号整型和无符号整型的比较中,自动将有符号整型 ...

  3. [转载]C++ 中有符号类型到无符号类型的转换(C和C++程序员面试秘笈P9面试题6)...

    本文复制自https://blog.csdn.net/abnerwang2014/article/details/20656423,是为了自己以后查看方便才复制过来的,谢谢原博主. 为了更好地解释下面 ...

  4. C语言中无符号整型变量赋值负数,负数时的有符号整型和无符号整型的转换

    目录 一.补码 二.负数时的有符号整型和无符号整型的转换 三.关于无符号的笔试题 一.补码 有符号数在计算机中存储,用数的最高位存放符号, 正数为0, 负数为1 例如:有符号数 1000 0011,其 ...

  5. 解决vs2013 error C4308: 负整型常量转换为无符号类型问题(转载)

    转自:http://blog.csdn.net/angle635/article/details/22035427 前面在学习使用google的protobuf时在VS2012中一直无法编译编译通过, ...

  6. C语言 有符号整型和无符号整型的比较

    C语言 有符号整型和无符号整型比较时,有符号整型自动转换成无符号整型,所以 10<-100 注意题给整数的范围,判断比较的整数类型

  7. php无符号整数转有符号整数,PHP中把有符号整型转换为无符号整型方法_PHP教程...

    PHP中把有符号整型转换为无符号整型方法 这篇文章主要介绍了PHP中把有符号整型转换为无符号整型方法,转换的方法很简单,本文直接给出转换方法,需要的朋友可以参考下 在一个短地址项目中,根据六位字符与I ...

  8. php 有符号整数,PHP中把有符号整型转换为无符号整型方法

    这篇文章主要介绍了PHP中把有符号整型转换为无符号整型方法,转换的方法很简单,本文直接给出转换方法,需要的朋友可以参考下 在一个短地址项目中,根据六位字符与ID的相互映射的算法,当ID超过214748 ...

  9. 负数时的有符号整型和无符号整型的转换

    目录 一.补码 二.负数时的有符号整型和无符号整型的转换 三.关于无符号的笔试题 一.补码 有符号数在计算机中存储,用数的最高位存放符号, 正数为0, 负数为1 例如:有符号数 1000 0011,其 ...

最新文章

  1. thinkphp的伪静态化
  2. 常用代码之三:jQuery为按钮绑定事件的代码
  3. BNF范式(巴科斯范式)简介
  4. Flink从入门到精通100篇(六)-Flink 应用之 对Release 文档进行深度解读
  5. Qt 进程 QProcess
  6. hive 字符串替换指定字符_hive学习笔记:substr()——字符串截取
  7. 全国计算机考试vb考试知识点汇总,全国计算机二级考试VB机试常见题型汇总
  8. WebLogic下载地址
  9. ant 编译android工程(转)
  10. [转]C# 将类的内容写成JSON格式的字符串
  11. ES6--那些新加入的数组方法
  12. java程序设计自考_java程序设计自考试题
  13. C#核编之格式化编程
  14. 第2章[2.4] Ext JS的类与类体系
  15. 从零学ELK系列(十一):SpringBoot项目接入ELK超级版(超详细图文教程)
  16. 小白初解Linux基础相关
  17. VS2017+Opencv3.3+Opencv_contribute编译
  18. C#调用C++编写的dll库
  19. python tkinter获取屏幕大小_使用Python构建属于自己的Markdown编辑器
  20. 思科网络安全解决方案

热门文章

  1. 知识蒸馏论文翻译(8)—— Knowledge Distillation Meets Self-Supervision(自监督)
  2. EXCEL条件格式 (二)
  3. FANUC机器人4种启动方式的具体操作步骤
  4. 临床医学计算机思维的应用情况,计算机模拟病例系统在医学生临床思维培养中应用价值分析.doc...
  5. 点评国内SNS网站-转帖
  6. GGAI重磅发布《自动泊车行业发展蓝皮书》: 竞争格局生变,谁在领跑市场?
  7. FreeRTOS系统定时器任务的实现
  8. 基于Android13的系统启动流程分析(六)之SystemServer内部逻辑分析
  9. Harbour.Space Scholarship Contest 2021-2022 (Div. 1 + Div. 2) -29
  10. codeforces_#242 (Div. 2)