C语言中的类型提升——基础概念,但还有很多人搞不清
来源:互联网 发布:淘宝周点数 编辑:程序博客网 时间:2024/05/21 12:45
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:gfree.wind@gmail.com
博客:linuxfocus.blog.chinaunix.net
今天主要说一下C语言的类型提升的事情。
下面是引用的一个例子——这个代码是从一个朋友的博文中复制过来的,但是当时这位朋友没有去说明类型提升的问题,而是阐述汇编的过程。
/***************************************************************/int main(){int i;unsigned char *p;char *p1;int a[] = {0xffffffff, 0xffffffff, 0xffffffff};p = a;p1 = a;for(i = 0 ; i < 8 ; i++) {printf(" 0x%02x 0x%02x \n", p[i], p1[i]);}}
$ gcc main.c
main.c: In function ‘main’:
main.c:10: warning: assignment from incompatible pointer type
main.c:11: warning: assignment from incompatible pointer type
$ ./a.out
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
0xff 0xffffffff
。。。。。。 。。。。。。
/***************************************************************/
根本原因其实很简单。
%x是打印无符号整数的16进制,而例子中传递的类型是字符型,那么这里就有一个字符提升的问题,将类型提升为无符号整形。
*p是unsigned char,其值为0xff,那么对应的无符号整形的值仍然是0xff。
而*p1确实char,其值为0xff,其对应的无符号整形的值为0xffffffff。为什么这次是0xffffffff呢?
因为*p1为-1,而无符号整数的-1则是0xffffffff。
为什么是这样呢?
因为在在编码为补码的情形下,类型提升有两种情况:
1. 符号扩展:对于有符号数,扩展存储位数的方法。在新的高位字节使用当前最高有效位即符号位的值进行填充。
2. 零扩展:对于无符号数,扩展存储位数的方法。在新的高位直接填0.
对于这个例子来说。*p是无符号数,所以填充的是0,即为0x000000ff。而*p1是有符号数,所以填充的是1,即为0xffffffff。
因此,从char型到unsigned int,是对有符号数的提升,因此用的是符号扩展,oxff被扩展为oxffffffff;而从unsigned char型到unsigned int型,是对无符号数的扩展,使用零扩展,oxff被扩展为ox000000ff,而填充的这些零是不会被打印出来的。
如果说这样教科书式的概念不容易理解。还有这样一种理解方式,也许不一定准确,但更容易理解。
对于这里的类型提升,整个步骤可以这样理解:
1. %x要求参数为无符号整数,需要参数为4个字节;
2. *p, *p1为(unsigned) char型,只占1个字节;
3. 因为参数的类型不符,需要扩展;
4. 定位需要扩展到4个字节;
5. 那么就需要填充增加的3个字节;
6. 这3个字节需要什么值?这里就需要上面所需要的概念了。针对有符号数和无符号数,进行不同值的填充。
这就是为什么在编程的过程中,要避免有符号数和无符号数的混用。我个人认为,在我们解决问题的时候,不要一味儿的想着怎么用高级的技术解决。其实最重要的是基础。一般情况下,大部分的问题都可以由C语言基础解决。
- C语言中的类型提升——基础概念,但还有很多人搞不清
- c++高级---C语言中的类型提升——基础概念,但还有很多人搞不清
- C语言中的类型提升——基础概念,但还有很多人搞不清
- C语言中的类型提升——基础概念,但还有很多人搞不清
- C语言中的类型提升和扩展
- c语言中的类型提升问题
- C语言 类型提升
- C语言类型提升
- 关于C语言中的 " 类型提升 "(type promotion)
- C语言的类型提升
- C语言的类型提升
- C语言的类型提升
- C语言基础—变量类型
- C语言模糊基础概念之强制类型转换
- C语言 — 整形提升
- C 语言中的整型提升
- c语言中的整形提升
- 黑马程序员————C语言基础概念
- Tyvj 1297 小气的小B
- ASP.NET页面间数据传递的方法
- ASP.NET MVC模型绑定的6个建议
- c# 通过ICallbackEventHandler 实现页面无刷新
- 程序员面试100题之六:最长公共子序列
- C语言中的类型提升——基础概念,但还有很多人搞不清
- JVM垃圾回收机制总结(1)
- UNIX/LINUX编程学习之进程通信--信号量
- 如何才算掌握Java(J2SE篇)
- JVM垃圾回收机制总结(2) :基本算法概述
- 程序员面试100题之七:最长公共子字符串
- 编译Windows版Android Emulator(Cupcake)
- JVM垃圾回收机制总结(3) :按代垃圾收集器
- JVM垃圾回收机制总结(4) :新一代的垃圾回收算法