第二章 数据类型
C语言中,对象引用到内存中的一个位置,该位置内容可表示为该对象的值。一个对象的数据类型决定了这个对象在内存中所占用的空间大小,以及所采用的编码方式
2.1整数类型
char类型也是一个标准的整数类型
C语言只定义了标准类型最小的存储空间,char类型只占用一个字节,short类型至少占用2字节,long类型至少占用4字节,long long类型至少占用8字节(1字节 == 8位)
2.1.1stdint.h头文件
stdint.h头文件定义了整数类型以满足对于已知位长的定义:
intN_t / uintN_t 位长为N的整数/无符号整数
int_leastN_t / uint_leastN_t 位长至少为N的整数/无符号整数
int_fastN_t / uint_fastN_t 位长至少为N的最快速的整数/无符号整数
intmax_t / uintmax_t 位长最大的整数/无符号整数
intptr_t / uintptr_t 位长足以存储指针值的整数/无符号整数
关于intptr_t的足以存储指针值的整数如何理解,我百度了一下它的宏定义:
/* Types for `void *' pointers. */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned long int uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned int uintptr_t;
#endif
显然,intptr_t不是指针类型,而是long int型。至于为什么解释成void *指针,尽管概念上地址是指针, 但内存管理常常使用一个无符号整型更好地完成。因为内核对待物理内存如同一个大数组,并且内存地址只是一个数组索引。而一个指针容易解引用,当直接处理内存存取时, 使用一个整数类型能避免这种解引用,因此避免了 bug。所以内核中内存地址常常是unsigned long型。(关于解引用,可以解释为返回内存地址中保存的值,关于它的解释找到一篇特别好的博文 跳转 )
2.1.2limits.h头文件
该头文件有很多宏定义,用于获得整数类型的范围,例如:INT_MIN,UINT_MAX,INT_LEAST64_MIN 等等
2.2浮点类型
关于浮点类型精度丢失的原因:
是因为我们在程序里写的是十进制小数,而计算机内部只能用二进制的小数表示, 所以导致无法精确的表达
对于二进制小数,小数点右边能表达的值是 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 … 1/(2^n),所以十进制小数都是由这些小数一点点拼凑出来的一个近似值, 所以才会不准确
例如用二进制来表示十进制的1.2:
1.01 = 1 + 1/4 = 1.25 , 偏大
1.001 = 1 + 1/8 = 1.125 , 偏小
1.0011 = 1 + 1/8 + 1/16 = 1.1875,偏小
1.001101 = 1 + 1/8+ 1/16 + 1/64 = 1.203125 , 偏大
1.0011001 = 1 + 1/8 + 1/16 + 1/128 = 1.1953125 ,偏小
1.00110011 = 1 + 1/8+1/16+1/128+1/256 = 0.19921875 , 偏小
直到越来越接近…这就是精度缺失的根本原因
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢