一、 为什么要引入数据类型
• 计算机中每个字节都有一个地址(类似门牌号)
• CPU通过 地址 来访问这个字节的空间
0x20001103 1 0 0 1 0 0 1 1
0x20001102 1 1 1 0 1 1 1 0
0x20001101 1 1 1 1 0 1 0 1
0x20001100 0 1 1 0 0 0 0 1(红色背景为地址)
施加int类型后,代表数值-290800982
施加int类型后,代表数值-290800982
• 对于计算机系统,二进制0和1数据没有任何意义
• 为了更接近现实生活,人为的规定了数据类型,便于有效组织管理这些数据
二、整型-数据类型的定义
1、整型的取值范围
• /usr/include/limits.h文件中,有数据类型范围的定义
# define SCHAR_MIN (-128)
# define SCHAR_MAX 127
# define UCHAR_MAX 255
# define INT_MIN (-INT_MAX - 1)
# define INT_MAX 2147483647
# define UINT_MAX 4294967295U
/* Minimum and maximum values a `signed long int' can hold. */
# if __WORDSIZE == 64
# define LONG_MAX 9223372036854775807L
# else
# define LONG_MAX 2147483647L
# endif
# define LONG_MIN(-LONG_MAX - 1L)
char:-128 ~ 127
short:-32768 ~ 32767
int:-2147483648 ~ 2147483647
long:-9223372036854775808 ~ 9223372036854775807
2、C语言中,如何获取某个数据类型所占用空间数?
sizeof 运算符
• sizeof是C语言中保留关键字,也是单目运算符。能获取某个数据类型所占用空间
的字节数。
• 使用形式:sizeof(变量名称) 或者 sizeof 变量名称 或者sizeof(数据类型)
int a;
sizeof(a) //√建议
sizeof a //√
sizeof(int)//√建议
sizeof int //×
三、变量的作用与用法
1、变量的作用
• 计算机中每一个字节的存储空间都有对应的地址,可以通过地址对其访问,进行读写操作。
0x20000000
• 若需要内存中存储一个整数58,怎么实现呢?
• C语言设计了变量的概念,变量用来在程序中保存数据比如: int val = 58; //声明一个int型变量val,CPU为val分配4个字节,可以存储数值58
• C语言提供了直接操作地址的功能,通过指针来访问某个地址空间,读写数据,后面再讲。
2、变量的用法
(1)变量的定义格式
ü关键字类型 变量名; int a;
ü关键字类型 变量名1,变量名2, ...; int a, b;
(2)如何进行变量赋值
变量初始化赋值,要使用赋值运算符=,可以初始化时赋值,也可以初始化后单独赋值:
ü 类型关键字 变量名 = 数值; int a = 20;
ü 类型关键字 变量名1 = 数值,变量名2 = 数值, ...; int a=10, b = 20
= 表示将”= ”右边的值赋给左边的变量
3、变量名要求
(1) 变量名以字母、数字、下划线组成;
(2) 变量名不能以数字、下划线开头;
(3) 变量名不能是关键字;
(4) 变量名不能包括空格、标点符合、和类型说明符。
4、变量的注意事项
nt num_1 = 5; //正确
int sum = 0; //正确
int 1_num = 5; //错误 不能数字开头
int %age = 18; //错误 不能有类型说明符(%、&、!、#、
@、¥)
int while = 23; //错误,while是C语言关键字
int name age = 10;//错误,不能有空格
变量必须先定义再使用
a = 100; //错误
int a;
变量在参与运算前,需要对其初始化:
int a;
int b;
b = a; //不会出现编译错误,但是存在运行风险,因为a的数值不确定。
5、变量扩展
下面三点,后续课程会深入讲解
① 变量的存储类型
auto
extern
register
static
② 局部变量和全局变量
③ 变量的作用范围
四、字符型变量
1、定义格式
char c1 = ‘A’;
char c2 = ‘a’;
char c3 = 66;
2、 注意字符常量要用单引号括起来,也可以用字符对应的ASCII码值进行赋值;
printf对应的格式符是%c;
五、浮点型-数据类型
1、浮点型
浮点型:用于存储小数,即数学中的实数
2、浮点数的表示形式
#include <stdio.h>
int main()
{
float f1 = 0.008;
float f2 = 8E-3;
float f3 = 8000;
float f4 = 8E+3;
printf("f1=%f,f2=%f\n", f1, f2);
printf("f3=%f,f4=%f\n", f3, f4);
return 0;
}
f1=0.008000
f2=0.008000
f3=8000.000000
f4=8000.000000
不论是浮点数形式,还是指数形式,输出效果是相同的
#include <stdio.h>
int main( )
{
float a = 1.12345678901234567890;
double b =
1.12345678901234567890;
long double c =
1.12345678901234567890;
printf("a = [%.30f]\n", a);
printf("b = [%.30lf]\n", b);
printf("c = [%.30Lf]\n", c);
return 0;
}
a = [1.123456835746765136718750000000]
b = [1.123456789012345691247674039914]
c = [1.123456789012345691247674039914]
绝大多数的浮点数是不能精确的表示的
3、计算机浮点数格式标准
IEEE-754标准规定:
• 单精度浮点数的最高位为符号位,S为0,正数,S为1,负数;
• 后面跟8位经偏移的阶码 (移码),偏移量为 127(科学计数法中,E可能为负数,所以规定,E的真实值需要再加上一个中间数,对于8位的E来说,中间数就是127
• 尾数用原码表示,且把尾数规格化为1.xxx,...x(x为0或1),并将1去掉,尾数用23位表示。
• 双精度浮点数的最高位为符号位
• 后面跟11位经偏移的阶码 (移码),偏移量为 1023,
• 尾数用原码表示,且把尾数规格化为1.xxx,...x(x为0或1),并将1去掉,尾数用52位表示。
举例:浮点数float 9.625 在内存中的存储
#include <stdio.h>
int main()
{
float f = 9.625;
printf("%#x\n", *(int *)&f);
return 0;
}
0x411a0000
4、浮点数怎么作比较
(1)浮点数存储的时候,存在精度损失,大多浮点数不是一个精确表示的数。
(2)在浮点数比较的时候,可不可以使用==进行比较?
测试程序1:
#include <stdio.h>
int main() {
double a = 1.0;
double b = 0.9;
if ((a - b) == 0.1) {
printf("equal\n");
}
else {
printf("not equal\n");
}
return 0;
}
not equal
测试程序2:
为了更好地进行代码分析,将 a - b 的值、 0.1 的值都打印
include <stdio.h>
int main() {
double a = 1.0;
double b = 0.9;
printf("%.30lf\n", a-b);
printf("%.30lf\n", 0.1);
return 0;
}
0.099999999999999977795539507497
0.100000000000000005551115123126
(3)浮点数跟零值进行比较
#include <stdio.h>
#include <math.h>
int main() {
double a = 1.0;
double b = 0.9;
double t = fabs((a - b) - 0.1);
if (t < 0.00000000000001 ){
printf("equal\n");
}
else {
printf("not equal\n");
}
return 0;
}
自定义精度:待比较的两个浮点数做减法,差值的绝对值小于精度,认为相等 ,反之不等
六、bool类型
1、_Bool类型-基础类型
• 从 C99 标准开始,增加了关键字 _Bool 用来表示布尔类型。
ü只能取值为 1 或 0
ü非零值为真,代表条件成立
ü零为假,代表条件不成立
ü占用的空间是1个字节,使用二进制的第0位来表示0和1
#include <stdio.h>
int main()
{
_Bool a;
a = -1;
if (a) {
printf("true %d\n", a);
}
else {
printf("false:%d\n", a);
}
printf("sizeof(_Bool)=%lu\n", sizeof(_Bool));
return 0;
}
true 1
sizeof(_Bool)=1
2、bool类型
• C99 中增加了一个头文件 stdbool.h。并在其中定义了bool、true 和 false
/usr/lib/gcc/x86_64-linux-gnu/11/include/stdbool.h
#define bool _Bool
#define true 1
#define false 0
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a;
a = 10;
if (a) {
printf("true:%d\n", a);
}
else {
printf("false:%d\n", a);
}
return 0;
}
true:1
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool f = false;
printf("f = %d\n", f);
f--;
printf("f = %d\n", f);
f--;
printf("f = %d\n", f);
f--;
printf("f = %d\n", f);
return 0;
}
七、void类型
• 该类型也叫缺省型,代表没有类型。
• 它通常被用作一种占位符,或用来表示“无返回值”的函数,或指向任一类型的指针等
void类型的用法:
(1)定义不返回任何值的函数
void printHelloWorld()
{
printf("Hello, World!");
}
(2)通用指针类型
void *指针类型通常称为通用指针类型。这种指针可以指向任何类型的数据。