"数据类型"读书小记
对于数据类型,虾米这个图应该很清楚了吧。
一、三个码
初学c的时候就对原码、反码、补码之类的不明白,一个简简单单的十进制数字为什么要用那么一大长串的01表示?真是多此一举。
后来才知道,语言电脑是非常笨的,他只能识别0和1两种数字,其他的数字 他都不认识。所以为了让人类和人工智能更好的交流,人类发明了二进制。
如果cpu里面生存有外星人的话,他们一定只有两根手指。
原码:计算机对数字的二进制表示方法,最高位符号位,0正1负。
反码:对原码各位取反得到,如果机器数是整数,反码 = 原码,若机器数是负数,反码 = 原码(取反)。
补码:如果机器数是整数,补码 = 原码,如果机器数是负数,补码 = 原码(除符号位外各位取反,并在末尾加1).
无符号数并不能表示负数,所以出现有符号数,但是原码表示有符号数会有问题。具体就不展开。
为了解决这两个问题,采用补码表示有符号数。
但是对于无符号数,三个码都是一样的,所以,整数在计算机中,使用补码表示。
二、溢出
在现在的计算机配置中,这并不是我们该担心的问题,我们目前 编的程序想要计算机溢出还是很困难的,除非你要处理全世界的人口问题。所以这个问题就不展开了。
数据类型 | 所占字节数 | 取值范围 |
---|---|---|
short | 2 | -32768~32767,即 -215~(215-1) |
unsigned short | 2 | 0~65535,即 0~(216-1) |
int | 4 | -2147483648~2147483647,即 -231~(231-1) |
unsigned int | 4 | 0~4294967295,即0~(232-1) |
long | 4 | -2147483648~2147483647,即 -231~(231-1) |
unsigned long | 4 | 0~4294967295,即0~(232-1) |
三、char与int
8位二进制数的整数数据类型就叫做 char。
一个例子说明他们的关系。
int i = 'a'; char c = 97; i = c;//安全,char可以赋给int c = i;// 不安全,int不能赋给char
不同的编译器,对char是否有符号都有自己的定义,但是暂且不管他。
四、浮点数的有效位
从理论上说,浮点数也存在溢出问题,但是就float所能表示的范围是10的负38次方到10的38次方,这已经是很大的范围了。
通常float类型的有效位只为6位或7位,当输出的位数大于这个值的时候,大于的位数都是编译器随机猜的了。
当时当判断两个浮点数是否相等的时候,有出现问题了,浮点数保存的时候都是近似值,所以不能直接比较,(这个只是点我真是第一次听说)。
要不是亲自试验一下,我还真不信。
int main()
{ float a = 0.33f; float c = 0.11f; c=c+0.22f; if(a == c) printf("equal."); //并不会输出
}
说道常量与常量后缀,常量后缀就是告诉编译器,请把我当成这种数据类型。这样可以编译器默认处理带来的潜在溢出或移植问题。
比如,10UL,表示这个是unsigned int;类型。
五、sizeof(指针)和sizeof(数组)的区别
参见博文:http://blog.sina.com.cn/s/blog_67b14f000100vkrz.html
引用如下/****************************
sizeof的意思是返回一个对象在内存中的字节数,是size_t类型的。
如果声明一个指针,比如 char* pstr = "hello";pstr是一个指针,那么sizeof(pstr)的值是4,
如果声明一个数组,比如 char pstr[] = "world";这时,pstr代表一个数组,那么sizeof(pstr)的值就是这个数组在内存中的字节数(包括\0)。
测试代码:
#include <stdio.h>
int main()
{
char str[] = "world", *pstr = "world";
printf("%d %d",sizeof(str),sizeof(pstr));
getchar();
return 0;
}
Dev-C++下编译通过,运行结果 6 4。
解释:
char str[] = "world";
这里初始化不限定长度,而"world"包含结束符'\0'后为6个字符,因此初始化str的长度是6;又因为char数组中每个元素(char变量)占用1个字节的空间,所以str[]数组的大小是6字节。
char *pstr = "world";
由于pstr是指针,无论是否指向字符串,指向什么字符串,sizeof(pstr)等于sizeof(int),32位平台上等于4。
造成差别的原因:
这里char str[] = "world";声明并定义了一个数组str[](当然,C语言的语法不允许在定义之外这样引用整个数组,以下这样的写法只是为了区分语义)。
标识符str有双重语义:一是如2L所说的类型为char* const的地址常量,它的值等于数组中首个元素的地址,即str等价于(char* const)&str[0];二是表示整个str[]数组这个语法对象。
在sizeof(str)中,str表示的含义是str[],因此返回整个数组的大小(这个大小在之前的数组定义中已经确定了);而pstr只是个指针,sizeof(pstr)只能返回指针本身占用的字节数而不能确定为它指向的内容分配的空间的大小。
注意,地址常量绝不是指针,类型不同!虽然在函数的参数传递过程中,地址常量可以退化成对应的指针。这里显然由于这个错误理解导致对数组的sizeof()结果判断有误。)