数据类型的介绍
基本数据类型
char //字符型 1字节
short //短整型 2字节
int //整型 4字节
long //长整型 4字节
long long //更长的整型 8字节
float //单精度浮点型 4字节
double //双精度浮点型 8字节
一个字节相当于8个比特位
类型的意义:
1.使用这个类型开辟内存空间的大小(大小决定了使用范围)。
类型的基本归类
整型:
char
//char符号的有无取决于编译器,通常看作有符号
unsigned char //无符号的
signed char //有符号的
short //有符号的
unsigned short [int] //无符号
signed short [int] //有符号
int //有符号
unsigned int //无符号
signed int //有符号
long //有符号
unsigned long [int] //无符号
signed long [int] //有符号
char 虽然是字符类型,但是字符类型存储的时候,存储的是字符的ascii码值,ascii值是整数。
有正负的数据存储于有符号的变量中
只有正数的数据存储于无符号的变量中
有符号的数据,最高位是符号位
最高位是0,表示正数
最高位是1,表示负数
对于无符号的数据而言,最高位也是数据位
浮点型:
float
double
long double
构造类型(自定义类型)
数组
结构体 struct
枚举 enum
联合 union
指针类型
int * ,char*,float *,void *;
指针用来存放地址
空类型
void 表示空类型(无类型)
通常应用于函数的返回类型,函数的参数,指针类型
例题1:
%d是打印有符号数,打印的是有符号数,不是有符号的数,也认为是有符号数
%u是打印无符号数,打印的是无符号数,不是无符号的数,也认为是无符号数
整型在内存中的存储
原码,反码,补码
整数可以写出三种二进制表示形式:
1.原码:直接将数值按照正负值的形式翻译成二进制
2.反码:原码的符号位不变,其他位按位取反
3.补码:反码加1
正数的原码,反码,补码都相同
负数的原码,反码,补码需要计算
对于整型来说:数据存放内存中存放的是补码
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程
是相同的,不需要额外的硬件电路。
平常打印出来的是原码,但是计算的时候使用的补码。
负数的补码-1得到反码,反码符号位不变其他按位取反得到原码
大端,小端
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地
址中。
例题1:
//判断大小端
#include<stdio.h>
int main()
{
int a = 1;
char* p = (char*)&a;//强制类型转换char指针,向后访问一个字节
if (*p == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
//函数的方法,函数的功能必须单一,只有判断功能就行
#include<stdio.h>
int check_sys()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
return 1;
else
return 0;
}
int check_sys()
{
int a = 1;
char* p = (char*)&a;
return *p;
}
int check_sys()
{
int a = 1;
return *(char*)&a;
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
打印无符号数和有符号数的区别
主要是看如何去使用
%u 是打印无符号数,意思是你要我打印的一定是无符号数,不是无符号数,我也认为是无符号数(此题中-10,-10的补码是个很大的数,打印无符号数,没有什么原反补码之分,直接打印补码)
%d是打印有符号数,意思是你要我打印的一定是有符号数,不是有符号数,我也认为是有符号数
(此题中,执行时存入-10的补码,但打印的是有符号数,所以将补码转化为原码打印出来)
例题
1.要点:char类型一个字节只能存储最后8个字节,打印时会发生整型提升。有符号类型就直接补符号位,对于无符号位的前面补0.
#include<stdio.h>
int main()
{
char a=-1;
//char 就是signed char
//-1的补码111111111111111111111111111111111
//char类型8个比特位11111111
//打印整型,发生整型提升,前面补符号位(符号位就是char 型11111111的第一位
//111111111111111111111111111111111
//打印原码就是-1
signed char b=-1;
//b同理
unsigned char c=-1;
//char类型只能存8个比特位11111111
//整型提升,对于无符号数前面直接补0;
//00000000000000000000000011111111
//直接打印补码
printf("a=%d,b=%d,c=%d",a,b,c);
//-1,-1,255
return 0;
}
#include<stdio.h>
int main()
{
char a=128;
//128 00000000000000000000000010000000
//char类 10000000
//打印时整型提升,是有符号char 类型 ,补1
//11111111111111111111111110000000补码
//打印的是无符号类型,原反补码相同
printf("%u\n",a);
return 0;
}
#include<stdio.h>
int main()
{
char a=-128;
//-128原码 10000000000000000000000010000000
//-128反码 11111111111111111111111101111111
//-128补码 11111111111111111111111110000000
//char类 10000000
//打印时整型提升,是有符号char 类型 ,补1
//11111111111111111111111110000000补码
//打印的是无符号类型,原反补码相同
printf("%u\n",a);
return 0;
}
相加转换成二进制,补码进行相加,看打印类型,是打印整型,转换成原码输出
#include<stdio.h>
int main()
{
int i = -20;
//原码10000000000000000000000000010100
//反码11111111111111111111111111101011
//补码11111111111111111111111111101100
unsigned int j = 10;
//00000000000000000000000000001010
printf("%d\n", i + j);
//11111111111111111111111111101100
//00000000000000000000000000001010
//11111111111111111111111111110110补码
//11111111111111111111111111110101反码
//10000000000000000000000000001010补码
return 0;//-10
}
为了运行时慢些,使用Sleep函数,单位是毫秒,要添加#include<windows.h>头文件
运行结果9-0,死循环
#include<stdio.h>
#include<string.h>
int main()
{
char a[1000];
for (int i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
//-1到-128,-128加1变成127,127-1,255个字符
printf("%d", strlen(a));
//strlen 求字符串长度,找的是\0的位置,统计\0前出现多少个字符
//\0的ascii码值是0
return 0;
}
unsigned 类型的计算
#include<stdio.h>
int main()
{
unsigned char a=200;
//00000000000000000000000011001000
//截断 11001000
unsigned char b=100;
//00000000000000000000000001100100
//截断 01100100
unsigned char c=0;
//c=a+b做加法,要整型提升
//a+b 00000000000000000000000100101100 300
//存放到c中时又发生截断 101100
//打印的是整型,所以要整型提升,符号位补0;
c=a+b;
printf("%d %d",a+b,c);
return 0;
}