目录
(1)数据类型介绍
数据类型的意义:
a.开辟内存空间的大小(大小决定了使用范围)
b.如何看待内存空间的视角(我们可以知道数据是什么类型)
(2)类型的基本归类
1)整型家族
char (unsigned char 、signed char)(因为存储的是ASCII码值)
short (unsigned short [int] 、signed short [int])
int( unsigned int 、signed int )
long(unsigned long [int] 、signed long [int])
2)浮点数家族
float
double
long double
3)构造类型(自定义类型)
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
4)指针类型
5)空类型
void
函数返回类型---void test();
函数参数---void test(void)
指针---void* p;
(3)整型在内存中的存储
1)以二进制存储
2)3种存储形式:原码、反码、补码
3)正整数:三种形式相同
负整数:以补码形式
4)Q:为什么要存补码?
A:使用补码,可以将符号位和数值域统 一处理
同时,加法和减法也可以统一处理(CPU只有加法器)
此外,补码与原码相互转换,其运算过程是相同的(不需要进行减1,再取反,只需要再进行一次取反再加1就可以),不需要额外的硬件电路
5)大小端
大端字节序:把数据低位字节序的内容存放在高地址处,高位字节序的内容存放在低地址处
小端字节序:把数据低位字节序的内容存放在低地址处,高位字节序的内容存放在高地址处
例题:请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。(10分)
解题思路:我们只需要判断第一个字节。
问题关键:怎么拿出第一个字节?答:使用char*。
具体实现:
int main()
{
int a = 1;
char* pa =(char*) &a;
if (*pa == 1)
{
printf("小端");
}
else
{
printf("大端");
}
return 0;
}
(4)练习-----输出什么?
第一题
#include <stdio.h>
int main()
{
char a= -1;
//补码:11111111 11111111 11111111 11111111
//整型截断---char:11111111
signed char b=-1;
//11111111 11111111 11111111 11111111
//整型截断---char:11111111
unsigned char c=-1;
//11111111 11111111 11111111 11111111
//整型截断---char:11111111
printf("a=%d,b=%d,c=%d",a,b,c);
//整型提升
//11111111 11111111 11111111 11111111---原码:-1(负数)
//11111111 11111111 11111111 11111111---原码:-1(负数)
//00000000 00000000 00000000 11111111---原码:255(正数)
return 0;
}
补充:
1)Q:char类型到底是 signed char还是unsigned char?
A:C语言标准并没有规定,取决于编译器
2)int 是 signed int、short 是 signed short
第二题
#include <stdio.h>
int main()
{
char a = -128;//改成128是一样的
//原码:10000000 00000000 00000000 10000000
//反码:10000000 00000000 00000000 01111111
//补码:11111111 11111111 11111111 10000000
//整型截断
//char:10000000
printf("%u\n",a);
//%u:打印符号整型
//整型提升
//补码:11111111 11111111 11111111 10000000
//原码:11111111 11111111 11111111 10000000(打印无符号,所以原码与补码相同)
return 0;
}
char的取值范围:-128~127 10000000~01111111
第三题
int i= -20;
//10000000 00000000 00000000 00010100
//11111111 11111111 11111111 11101011
//11111111 11111111 11111111 11101100
unsigned int j = 10;
//补码:00000000 00000000 00000000 00001010
printf("%d\n", i+j);
//i+j---
//补码:11111111 11111111 11111111 11110110
//反码:11111111 11111111 11111111 11110101
//补码:10000000 00000000 00000000 00001010
//按照补码的形式进行运算,最后格式化成为有符号整数
第四题
unsigned int i;
for(i = 9; i >= 0; i--)
{
printf("%u\n",i);
}
//死循环
第五题
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
//255
//从-1开始减1:-1~-128,再从-128->-129,转化成原码后也就是127,从127减1最后到1,然后循环
//因为strlen函数遇到'\0'就会停止,所以遇到0时结束,所以求出来是255
//因为在char的范围中:-128~127
//char类型中只能存下-128~127
第六题
#include <stdio.h>
unsigned char i = 0;//unsigned char的范围是0~255,然后循环
int main()
{
for(i = 0;i<=255;i++)
{
printf("hello world\n");
}
return 0;
}
//死循环
(5)浮点型在内存中的存储
1)浮点数表示的范围
float.h中定义
2)浮点数存储的例子
*pFloat是以浮点数的视角去看的
从上例可知,浮点数和整型的存储方式是不同的
3)浮点数存储规则
1)根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数可以表示成下面的形式:
(-1)^s * M * 2^E。
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
2)举例:
十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。
那么,按照上面的格式,可以得出s=0,M=1.01,E=2。
十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。
那么,s=1,M=1.01,E=2。