二、数据类型
1、常量与变量
1.1、关键字
- C语言关键字有32个
- 数据类型关键字(12个)
- char、short、int、long、float、double、usigned、signed、struct、union、enum、void。
- 控制语句关键字(12个)
- if、else、switch、case、default、for、do、while、break、continue、goto、return。
- 存储类关键字(5个)
- auto、extern、register,static、const
- 其他关键字(3个)
- sizeof、typedef、volatile
1.2、数据类型
- 数据类型的作用:编译器预算对象(变量)分配的内存空间大小
1.3、常量
-
在程序运行过程中,其值不能被改变的量
-
常量一般出现在表达式或赋值语句中
类型 具体事例 整型常量 100,200,-100,0 实型常量 3.14,0.11,-3.14 字符型常量 ‘a’,‘b’,‘c’,‘d’ 字符串常量 “a”,“bbb”,“12233”
1.4、变量
-
在程序运行过程中,其值可以改变
-
变量在使用前必须先定义,定义变量前必须有相应的数据类型
-
标识符命名规则
- 标识符不能是关键字(32个关键字)
- 只能由字母、数字、下划线组成
- 第一个字符必须是由字母或下划线
- 标识符中字母区分大小写
- 最好见名知意
-
变量的特点
-
变量在编译时为其分配相应存储空间
-
可以通过其名字和地址访问相应内存
-
-
声明和定义区别
- 声明变量不需要建立存储空间,如:extern int a;
- 定义变量需要建立存储空间,如:int b;
- 从广义的角度来说声明包含着定义,定义是声明的一个特例,所以并非所有的声明都是定义
- int b它既是声明,同时也是定义。
- 对于extern b 来讲它只是声明不是定义
2、整型:int
2.1、整型变量的定义和输出
打印格式 | 含义 |
---|---|
%d | 输出一个由符号的10进制int类型 |
%o | 输出8进制的int类型 |
%x | 输出16进制的int类型,字母以小写输出 |
%X | 输出16进制的int类型,字母以大写输出 |
%u | 输出一个10进制的无符号数 |
#include<stdio.h>
int main()
{
int a = 123;//定义变量a,以10进制方式赋值为123
int b= 0567;//定义变量b,以8进制方式赋值为0567
int c = 0xabc;//定义变量c,以16进制方式放置为0xabc
printf("a = %d\n", a);
printf("8进制:b = %o\n", b);
printf("10进制:b = %d\n", b);
printf("16进制:c = %x\n", c);
printf("16进制:c = %X\n", c);
printf("10进制:c = %d\n", c);
unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
printf("有符号方式打印:d = %d\n", d);
printf("无符号方式打印:d = %u\n", d);
return 0;
}
2.2、整型变量的输入
#include <stdio.h>
int main()
{
int a;
printf("请输入a的值:");
//不要加“\n”
scanf("%d", &a);
printf("a = %d\n", a); //打印a的值
return 0;
}
2.3、short、int、long、long long
数据类型 | 占用空间 |
---|---|
short短整型 | 2字节 |
int整型 | 4字节 |
long长整型 | Windows为4字节,linux为4字节(32位),8字节(64位) |
long long长长整型 | 8字节 |
- 需要注意的是,整型数据在内存中的字节数与所选择的操作系统有关,虽然C语言标准中没有明确规定整型数据的长度,但long类型整数的长度不能短于int 类型,short类型整数不能长于int类型
- 当一个小的数据类型转换给一个大的数据类型,不会报错,因为编译器会自动转换,但是当一个大的数据类型赋值给小的数据类型的时候,那么就有可能丢失精度。
2.4、有符号数和无符号数的区别
- 有符号数
- 有符号数是最高位为符号位,0代表整数,1代表负数。
- 无符号数
- 无符号数最高位不是符号位,而就是数的一部分,无符号数不可能是负数。
- 当我们写程序要处理一个不可能出现负值的时候,一般用无符号数,这样可以增大数的表达最大值
3、sizeof关键字
-
sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个暑假类型的大小,单位是字节
-
sizeof的返回值为size_t
-
size_t类型在32位操作徐彤下是unsigned int,是一个无符号的整数
#include <stdio.h> int main() { int a; int b = sizeof(a);//sizeof得到指定值占用内存的大小,单位:字节 printf("b = %d\n", b); size_t c = sizeof(a); printf("c = %u\n", c);//用无符号数的方式输出c的值 return 0; }
4、字符型:char
4.1、字符变量的定义和输出
-
字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节。在给字符型变量赋值时,需要用一对英文半角格式的单引号(’ ')把字符括起来。
字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char的本质就是一个1字节大小的整型。
4.2、字符变量的输入
#include <stdio.h>
int main()
{
char ch;
printf("请输入ch的值:");
//不要加“\n”
scanf("%c", &ch);
printf("ch = %c\n", ch); //打印ch的字符
return 0;
}
4.3、ASCII表(无)
4.4、转义字符
转义字符 | 含义 | ASCII****码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\ | 代表一个反斜线字符"" | 092 |
’ | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0~7 | 3位8进制 |
\xhh | 16进制转义字符,h范围09,af,A~F | 3位16进制 |
5、实型(浮点型):float、double
- 实型变量也可以成为浮点型变量,浮点型变量是用来存储小数数值的,在C语言中,浮点型变量分为两种,单精度浮点数(float),双精度浮点数(double)但是double类型变量所表示浮点数比float行变量更加精确。
- 由于浮点型变量是有限的存储单元组成,因此只能提供有限的有效数字
- 在有效为以为的数字将被舍去,这样可能会产生一些误差。
- 不以f结尾的常量是double类型,以f结尾的常量(如:3.14f)是float类型
6、进制
6.1、二进制
- 二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。
- 当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。
术语 | 含义 |
---|---|
bit(比特) | 一个二进制代表一位,一个位只能表示0或1两种状态。数据传输是习惯以“位”(bit)为单位。 |
Byte(字节) | 一个字节为8个二进制,称为8位,计算机中存储的最小单位是字节。数据存储是习惯以“字节”(Byte)为单位。 |
WORD(双字节) | 2个字节,16位 |
DWORD | 两个WORD,4个字节,32位 |
1b | 1bit,1位 |
1B | 1Byte,1字节,8位 |
1k,1K | 1024 |
1M(1兆) | 1024k, 1024*1024 |
1G | 1024M |
1T | 1024G |
1Kb(千位) | 1024bit,1024位 |
1KB(千字节) | 1024Byte,1024字节 |
1Mb(兆位) | 1024Kb = 1024 * 1024bit |
1MB(兆字节) | 1024KB = 1024 * 1024Byte |
7、计算机内存数值存储方式
7.1、原码
-
最高位作为符号位,0表示正,为1表示负
-
其他数值部分就是数值本身绝对值的二进制数
-
负数的原码是在其绝对值的基础上,最高位为1
-
下面数值以1字节的大小描述:
十进制数 | 原码 |
---|---|
+15 | 0000 1111 |
-15 | 1000 1111 |
+0 | 0000 0000 |
-0 | 1000 0000 |
- 原码表示法简单易懂,与带符号数本身转换方便,只要符号还原即可,但当两个正数相减或不同符号数相加时,必须比较两个数哪个绝对值大,才能决定谁减谁,才能确定结果是正还是负,所以原码不便于加减运算。
7.2、反码
-
对于正数,反码与原码相同
-
对于负数,符号位不变,其他部分取反(1变0,0变1)
十进制数 反码 +15 0000 1111 -15 1111 0000 +0 0000 0000 -0 1111 1111 -
反码运算也不方便,通常用来作为求补码的中间过渡。
7.3、补码
-
在计算机系统中,数值一律用补码来存储。
-
补码的特点
-
对于正数,原码、反码、补码相同
-
对于负数,其补码为它的反码加1
-
补码符号位不动,其他位求反,最后整个数加1,得到原码
十进制数 补码 +15 0000 1111 -15 1111 0001 +0 0000 0000 -0 0000 0000
-
7.4、补码的意义
-
示例1:用8位二进制数分别表示+0和-0
十进制数 原码 +0 0000 0000 -0 1000 0000 十进制数 反码 +0 0000 0000 -0 1111 1111 -
不管以原码方式存储,还是以反码方式存储,0也有两种表示形式。为什么同样一个0有两种不同的表示方法呢?
-
但是如果以补码方式存储,补码统一了零的编码:
十进制数 补码 +0 0000 0000 -0 10000 0000由于只用8位描述,最高位1丢弃,变为0000 0000 示例2:计算9-6的结果
以原码方式相加:
十进制数 原码 9 0000 1001 -6 1000 0110 结果为-15,不正确。
以补码方式相加:
十进制数 补码 9 0000 1001 -6 1111 1010 最高位的1溢出,剩余8位二进制表示的是3,正确。
-
-
在计算机系统中,数值一律用补码来存储,主要原因是:
- 统一了零的编码
- 将符号位和其他位统一处理
- 将减法运算转变为加法运算
- 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃
7.5、数值溢出
-
当超过一个数据类型能够存放最大的范围时,数值会溢出
-
有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。
数据类型 | 占用空间 | 取值范围 |
---|---|---|
char | 1字节 | -128到 127(-27 ~ 27-1) |
unsigned char | 1字节 | 0 到 255(0 ~ 28-1) |
8、类型限定符
限定符 | 含义 |
---|---|
extern | 声明一个变量,extern声明的变量没有建立存储空间。 extern int a;//变量在定义的时候创建存储空间 |
const | 定义一个常量,常量的值不能修改。 const int a = 10; |
Volatile | 防止编译器优化代码 |
register | 定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。 |
9、字符串格式化输入和输出
9.1、字符串常量
-
字符串常量是内存中一段连续的char空间,以’\0’结尾。
-
字符串常量是由双引号括起来的字符序列,如:“chaina”、“C”、“¥123.1”都是合法的字符串常量
-
字符串常量与字符常量的不同
-
每个字符串的结尾,编译器会自动的添加一个结束标志位’\0’,即 “a” 包含两个字符’a’和’\0’。
9.2、printf函数和putchar函数
-
printf是输出一个字符串,putchar输出一个char。
-
printf格式字符:
打印格式 对应数据类型 含义 %d int 接受整数值并将它表示为有符号的十进制整数 %hd short int 短整数 %hu unsigned short 无符号短整数 %o unsigned int 无符号8进制整数 %u unsigned int 无符号10进制整数 %x,%X unsigned int 无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF %f float 单精度浮点数 %lf double 双精度浮点数 %e,%E double 科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写 %c char 字符型。可以把输入的数字按照ASCII码相应转换为对应的字符 %s char * 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符) %p void * 以16进制形式输出指针 %% % 输出一个百分号 -
printf附加格式:
字符 含义 l(字母l) 附加在d,u,x,o前面,表示长整数 - 左对齐 m(代表一个整数) 数据最小宽度 0(数字0) 将输出的前面补上0直到占满指定列宽为止不可以搭配使用- m.n(代表一个整数) m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
9.3、scanf函数与getchar函数
- getchar是从标准输入设备读取一个char。
- scanf函数通过%转义的方式可以得到用户通过标准输入设备输入的数据