目录
一、数据类型介绍
C语言基本的内置类型:
char //字符数据类型
short //短整型
int //整型
long //长整型
long long // 更长整型
float //单精度浮点数
doublt //双进度浮点数
1、 类型归类:
1>、整型家族:
char (字符在内存中是以ASCII值的形式存储,ASCII是整数,所以char可以归类到整型家族中)
unsigned char (无符号字符)
signed char (有符号字符)
short
unsigned short [int]
signed short [int] 在C语言中规定(short = singed char),int long 同理
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
注释:char和 short、int、long 不同 ,c语言语法没有明确规定,若需要有符号char,用signed char ;需要无符号char,用unsigned char。
2>、浮点型家族:
float (单精度浮点数)
doublt (双精度浮点数)
3>、构造类型:(自定义类型)
1>、数组类型
2>、结构体类型 struct
3>、枚举类型 enum
4>、联合类型 union
4>、 指针类型
int *pi;
char *pc;
float *pf;
void *pv;
5>、空类型:
void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型。
二、整形在内存中的存储
1、原码、反码、补码
在计算机系统中,数据一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时、加法和减法也可以统一处理(cpu只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
原码、反码、补码相关知识点,从下面链接查看
补充:
1、数据类型与原码、反码、补码练习
#include<stdio.h>
int main()
{
char a = -1;
//在内存中存储的是补码
//10000000000000000000000000000001 —— -1的原码
//11111111111111111111111111111110 —— -1的反码
//11111111111111111111111111111111 —— -1的补码
//11111111 -a ,发生截断
signed char b = -1;
unsigned char c = -1;
//11111111111111111111111111111111 —— -1的补码
//11111111 -c ,当在unsigned char 的环境下-1发生截断后,第一位代表的就不是符号位,他也
//就是数值位
printf("a = %d,b = %d, c = %d",a,b,c);//以%d形式打印,打印的是整型,补码是32位bit
//位,所以在打印的时候要进行整型提升.
//a 整型提升
//11111111 有符号数整型提升的时候按符号位提升(高位补符号位)。
//10000000000000000000000000000001 ——提升后的原码,整型提升后是-1
//c 整型提升
//11111111 无符号数整型提升的时候高位直接补0
//00000000000000000000000011111111
return 0;
}
结果是:-1 -1 255
注释:以signed char 和unsigned char 为例:
整形提升的时候 :有符号数整型提升的时候按位提升(高位补符号位)。
无符号数整型提升的时候高位直接补0。
2、有符号数和无符号数的取值范围如何确定
以signed char与unsigned char 在内存中的存储(以补码的形式存储)为例
同理:signed short 的取值范围是 -32768~32767;unsigned short 的取值范围是0~65535。
int 、long、等等都可以用这个思想来确定。
练习:
1、
#include<stdio.h>
int main()
{
char a = -128;
//10000000000000000000000010000000 —— -128的原码
//11111111111111111111111101111111 —— -128的反码
//11111111111111111111111110000000 —— -128的补码
//10000000 —— -存入a中,发生截断
//%u 打印无符号整型,认为内存中存放的补码对应的是一个无符号数
//%d 打印有符号整型,认为内存中存放的补码对应的是一个无符号数
printf("%u\n",a);//整型提升 ,提升a就看a在当前编译器中为有符号char,按符号位提升。
//11111111111111111111111110000000 —— -提升后的补码
//因为提升后为无符号整型,则补码、原码相同,并且首位算入数值位。
return 0;
}
结果是:4294967168
注释:如上述代码,打印时发生整形提升,
1、首先看要提升的数在当前代码中,是否为有符号类型的数(如:signed char),若是, 则按符号位提升,若是无符号类型的数(如:unsigned char),高位直接补0。
2、提升完成后,再看要求提升的是有符号还是无符号的数.在做相应的补码与原码的转换。
2、
#include<stdio.h> #include<windons.h> int main() { unsigned int i; for(i = 9;i >= 0;i--) { printf("%u\n",i); Sleep(100);//睡眠函数,防止打印过程太快 } } 结果是:0~9~死循环
因为是无符号整型,当i=0之后,代码不会停止,通过i--,得到unsigned int 类型的取值范围中的最大值。
3、
#include<stdio.h> int main() { char a[1000]; int i; for(i = 0;i < 1000;i++) { a[i] = -1 -i; } printf("%d",strlen(a));//strlen是以字符\0为结束标志,\0的ASCII码值是0,所以找到数组中 //0以前的字符,出现多少字符就是多少长度。 return 0; } 结果是:255
char类型的取值范围是-128~127,127+128=255之后是0,0之前有255个字符,所以函数strlen得到的长度为255.
三、大小端字节序
如上述图片 代码中输入的16进制数的顺序与内存中的存储顺序是相反的。在这里就要提到大小端字节序的知识点。
1、概念
字节序,就是大于一个字节类型的数据在内存中的存放顺序。
2、大小端介绍(以字节为单位来进行研究)
字节序经常被分为两类:
1>、大端(存储)模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
2>、小端(存储)模式:是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
3、理解(高低地址和高低字节)
1>、高低字节
以0x11223344,这个16进制数字为例:
在十进制中靠近左边是高位,靠近右边是低位,在其他进制中也是一样。
0x11223344,从高位到低位的字节依次是 0x11,0x22,0x33,0x44.
2>、高低地址
在栈区:(从高内存地址,到低内存地址。即从栈底(高地址),到栈顶(低地址))。
上述例子,小端存储 0x44是低字节,其所在位置是地址的首位,是内存的低地址 。
练习:请设计一个小程序来判断当前机器的字节序
#include<stdio.h>
int main()
{
int a = 1;
char *p = (char*)&a;//强制类型转换为char*类型,通过char*类型的指针查找int类型在内存中
//的第一个字节的内容来判断大小端。
if(1 == *p)
printf("小端\n");
else
printf("大端\n");
return 0;
}