1.数据类型
1.1 基本数据类型
数据类型分2类:基本数据类型+复合类型
基本类型:
char
short
int
long
float
double
复合类型:数组 结构体 共用体 类(C语言没有类,C++有)
1.2 内存占用与sizeof运算符
数据类型就好像一个一个的模子,这个模子实例化出C语言的变量。变量存储在内存中,需要占用一定的内存空间。一个变量占用多少空间是由变量的数据类型决定的。
每种数据类型,在不同的机器平台上占用内存是不同的。我们一般讲的时候都是以32位CPU为默认硬件平台来描述:
char 1字节 8位
short 2字节 16位
int 4字节 32位
long 4字节 32位
float 4字节
double 8字节
1.3 有符号数和无符号数
对于char short int long等整形类型的数,都分有符号有无符号数。
而对于float和double这种浮点型数来说,只有有符号数,没有无符号数。
对于C语言来说,数(也就是变量)是存储在内存中一个一个的格子中的。存储的时候是以二进制方式存储的,对于有符号数和无符号数来说,存储方式不同的。
譬如对于int来说
- unsigned int 无符号数,32位(4字节)全部用来存数的内容 所以表示的数的范围是0 ~ 4294967295(2^32 -1)
- signed int 有符号数,32位中最高位用来存符号(0表示正数,1表示负数),剩余的31位用 来存数据。所以可以表示的数的范围是 -2147483648(2^32) ~ 2147483647(2 ^31 - 1)
结论:从绝对数值来说,无符号数所表示的范围要大一些。因为有符号数使用1个二进制位来表示正负号。
1.4 整形数和浮点型数存储方式上的不同
对于float和double这种浮点类型的数,它在内存中的存储方式和整形数不一样。所以float和int相比,虽然都是4字节,但是在内存中存储的方式完全不同。所以同一个4字节的内存,如果存储时是按照int存放的,取的时候一定要按照int型方式去取。如果存的时候和取的时候理解的方式不同,那数据就完全错了。
总结:存取方式上主要有两种,一种是整形一种是浮点型,这两种存取方式完全不同,没有任何关联,所以是绝对不能随意改变一个变量的存取方式。在整形和浮点型之内,譬如说4种整形char、short、int、long只是范围大小不同而已,存储方式是一模一样的。float和double存储原理是相同的,方式上有差异,导致了能表示的浮点型的范围和精度不同。
1.5 空类型(关键字void)
C语言中的void类型,代表任意类型,而不是空的意思。任意类型的意思不是说想变成谁就变成谁,而是说它的类型是未知的,是还没指定的。
void * 是void类型的指针。void类型的指针的含义是:这是一个指针变量,该指针指向一个void类型的数。void类型的数就是说这个数有可能是int,也有可能是float,也有可能是个结构体,哪种类型都有可能,只是我当前不知道。
void型指针的作用就是,程序不知道那个变量的类型,但是程序员自己心里知道。程序员如何知道?当时给这个变量赋值的时候是什么类型,现在取的时候就还是什么类型。这些类型对不对,能否兼容,完全由程序员自己负责。编译器看到void就没办法帮你做类型检查了。
在函数的参数列表和返回值中,void代表的含义是:
一个函数形参列表为void,表示这个函数调用时不需要给它传参。
返回值类型是void,表示这个函数不会返回一个有意义的返回值。所以调用者也不要想着去使用该返回值。
C语言设计基本理念:
C语言相信程序员永远是对的,C语言相信程序员都是高手,C语言赋予了程序员最大的权利。所以C语言的程序员必须自己对程序的对错负责,必须随时脑袋清楚,知道自己在干嘛。
1.6 数据类型转换
C语言中有各种数据类型,写程序时需要定义各种类型的变量。这些变量需要参与运算。C语言有一个基本要求就是:不同类型的变量是不能直接运算的。
也就是说,int和float类型的变量不能直接加减等运算。你要运算,必须先把两种类型转成相同的类型才可以。
1.6.1 隐式转换
隐式转换就是自动转换,是C语言默认会进行的,不用程序员干涉。
C语言的理念:隐式类型转换默认朝精度更高、范围更大的方向转换。
1.6.2 强制类型转换
C语言默认不会这么做,但是程序员我想这么做,所以我强制这么做了。
测试代码
#include<stdio.h>
int main()
{
int a = 3;
float b = 4.6;
//printf ("a + b = %d\n",a+b); //(1)
//printf ("a + b = %f\n",a&