1.常量和变量
(1).常量:在程序使用之前已经预先设定好,在整个程序的运行过程中没有变化
(2).变量:在程序运行期间可能会被改变或被赋值
2.数据类型关键字
最初K&R给出的关键字 | C90标准添加的关键字 | C99标准添加的关键字 |
int | signed | _Bool |
long | void | _Complex |
short | _Imaginary | |
unsigned | ||
char | ||
float | ||
double |
通过这些关键字创建的类型,按计算机的存储方式可分为两大基本类型:整数类型和浮点数类型
3.位、字节和字
位、字节和字是描述计算机数据单元或存储单元的术语(这里主要指存储单元)
(1).最小的存储单元是位(bit),可以存储0或1.位是计算机内存的基本构建块。
(2).常用的计算机存储单位是字节(byte),1字节等于8位。
(3).设计计算机时给定的自然存储单位是字(word)。计算机的字长越大,其数据转移越快,允许的内存访问也更多。
4.整数和浮点数
对计算机而言,整数和浮点数的区别是存储方式的不同。
(1).计算机以二进制数字存储整数(0、1)
例:
(2).计算机把浮点数分成小数部分和指数部分来表示,而且分开储存
例:
5.C语言基本数据类型
一、int类型(C语言规定int类型不小于16位)
(1). int类型是有符号整型,即int类型的值必须是整数,可以是正整数、负整数或零
(2).ISO C规定int的取值范围最小为-32678~32767
(3).一般而言,系统用一个特殊位的值表示有符号整数的正负号
1.声明int变量
例: int erns;
int age,hour,day;
注:以上声明只是创建了变量并分配了内存空间,并没有给它们赋值
2.初始化变量
例: int erns = 60;
int age = 22,hour = 23,day = 25;
注:初始化变量就是为变量赋一个初始值。在C语言中,初始化可以直接在声明中完成
3.int类型常量
C语言把不含小数点和指数的数作为整数,通常在int类型取值范围内都为int类型
例: 25,68,1,999都是整型常量
22.0,2.5E1则不是
4.打印int值
c 使用printf()函数打印int类型的值(确保转换说明的数量与待打印的数量相等);
例: int age = 22;
printf("age = %d\n",age);
注: (1).%d称为转换说明,指明了在一行中打印整数的位置,指定了printf()应使用什么格式来显示一个值
(2).格式化字符串中的每个%d都与待打印变量列表中相应的int值匹配
(3).这个值可以是int类型的变量、int类型的常量或其他任何值为int类型的表达式
5.八进制和十六进制
(1).0x或0X前缀表示十六进制(例: 十进制16表示成十六进制是0x10或0X10)
(2).0前缀表示八进制(例: 十进制16表示成八进制是020)
注:使用不同的进制是为了方便,不会影响数被存储的方式,计算机内部都以二进制进行编码
6.显示八进制和十六进制
(1).以十进制显示数字,使用%d;
(2).以八进制显示数字,使用%o;
(3).以十六进制显示数字,使用%x;
注: 显示各进制数的前缀0、0x、0X必须分别使用%#o、%#x、%#X
例: int num = 100;
printf("dec = %d,octal = %o,hex = %x\n", num, num, num);
printf("dec = %d,octal = %#o,hex = %#x\n", num, num, num);
打印结果为:
dec = 100,octal = 144,hex = 64
dec = 100;octal = 0144,hex = 0x64
二、其他整数类型
C语言提供了三个附属关键字修饰基本整数类型:short、long、unsigned
(1).short int类型(short): 占用的存储空间可能比int类型少,常用于较小数值的场合以节省空间(有符号类型)
(C语言规定short类型不小于16位)
(2).long int类型(long): 占用的存储空间可能比int多,适用于较大数值的场合(有符号类型)
(C语言规定long类型不小于32位)
(3).long long int类型(long long): 占用的存储空间可能比long多,适用于更大数值的场合(有符号类型)
(C语言规定long long类型不小于64位)
(4).unsigned类型(unsigned): 只用于非负值的场合(0和正整数)
注:这种类型与有符号类型表示的范围不同,用于表示正负号的位用于另一个二进制位,所以无符号整型可以表示更大的数
例: 16位unsigned int的取值范围为0~65535,而不是有符号int整型的取值范围-32768~32767
(5).在任何有符号类型前面添加关键字signed,可强调使用有符号类型的意图
1.声明其他整数类型
(1).声明长整型变量
例: long int money; 或 long money;
(2).声明短整型变量
例: short int age; 或 short age;
(3).声明无符号整型变量
例: unsigned int score; 或 unsigned score;
(4).声明无符号长整型变量
例: unsigned long headcount;
(5).声明无符号短整型变量
例: unsigned short hours;
2.整数溢出举例(以int 型为例,32位机器int型取值范围为[-2147483648,2147483647])
例: int i = 2147483647;
unsigned int j = 4294967295;
printf("%d %d %d\n", i, i + 1, i + 2);
printf("%u %u %u", j, j + 1, j + 2);
输出结果为: 2147483647 -2147483648 -2147483647
4294967295 0 1
注: 在超过最大值时,unsigned int类型的变量从0开始;而int类型变量从-2147483648开始
溢出行为是未定义的行为,C标准并未定义有符号类型的溢出规则
3.打印short、long、long long和unsigned类型变量
(1).打印unsigned int类型的值,可以用%u转换说明;
例: unsigned int num = 600000;
printf("%u\n",num);
(2).打印short类型的值,可以用%d或者%hd转换说明;
例: short int num = 200;
printf("%hd\n",num); //以十进制打印short类型变量num
printf("%ho\n",num); //以八进制打印short类型变量num
(3).打印long类型的值,可以用%ld转换说明
例: long int num = 88888;
printf("%ld\n",num); //以十进制打印long类型变量num
printf("%lo\n",num); //以八进制打印long类型变量num
printf("%lx\n",num); //以十六进制打印long类型变量num
(5).打印unsigned short类型的值,可以用%hu转换说明;
例: unsigned short num = 200;
printf("%hu\n",num);
(6).打印unsigned long类型的值,可以用%lu转换说明;
例: unsigned long num = 600000;
printf("%lu\n",num);
三、char类型(1字节)
char类型用于储存字符(如大小写字母、标点符号),但是从技术层面看,char是整数类型。
(1).计算机使用数字编码来处理字符,即使用特定的整数表示特定的字符(ASCII码)
(2).标准ASCII码的范围是0~127,只需7位二进制数即可表示
1.声明char类型变量
例: char ch;
char c,sign;
2.字符常量和初始化
例: char grade = 'B'; 或 char grade = 66;
注: 用单引号括起来的单个字符被称为字符常量,字符是以数值形式储存的,所以也可以使用数字代码值来赋值
3.转义序列(使用特殊的符号序列表示一些特殊的字符)
转义序列 | 含义 | 转义序列 | 含义 | 转义序列 | 含义 |
\a | 警报(ANSIC) | \t | 水平制表符 | \? | 问号 |
\b | 退格 | \v | 垂直制表符 | \0oo | 八进制值 |
\f | 换页 | \\ | 反斜杠(\) | \xhh | 十六进制值 |
\n | 换行 | \' | 单引号 | ||
\r | 回车 | \" | 双引号 |
例: 打印Hello,"a\ is a backslash."
printf("Hello,\"a\\ is a backslash.\"\n");
例: float salary;
printf("\a请输入你想要的月薪: "); //警报 \a
printf("$__________\b\b\b\b\b\b\b"); //退格 \b
scanf("%f", &salary); //输入月薪
printf("\n\t$%.2f 一个月,一年%.2f", salary, 12.0*salary); //换行 \n 水平制表符 \t
printf("\r加油!\n"); //回车 \r
例: 假设ch是char类型的变量,分别使用转义序列、十进制值、八进制字符常量和十六进制字符常量把回车字符赋给ch
(使用ASCII编码值)
ch = '\r'; //转义序列
ch = 13; //十进制
ch = '\015'; //八进制
ch = '\xd' //十六进制
4.打印字符(printf()函数用%c指明待打印的字符,如果用%d转换说明打印char类型变量的值)
例:char ch = 'c';
printf("%c\n",ch); //输出结果为c
printf("%d\n",ch); //输出结果为99
注: printf()函数中的转换说明决定了数据的显示方式,而不是数据的储存方式
四、_Bool类型(布尔类型是无符号int类型,所占用的空间只要能储存0或1即可)
C99标准添加了_Bool类型,用于表示布尔值。即逻辑值true和false;
在C语言中用值1来表示true,用值0来表示false;
五、float类型和double类型
(1).通常系统存储一个float型变量要占用32位,8位用于表示指数的值和符号,24位用于表示非指数部分(尾数或有效数)及其符号
系统的基本浮点类型(单精度浮点小型),可精确表示6位有效数字
(2).通常系统存储一个double型变量要占用64位
双精度浮点型,至少精确表示10位有效数字和更大的指数
1.声明float类型变量和double类型变量(与整型变量相同,只是类型不同)
例:float num; //声明单精度浮点类型float变量num
double height; //声明双精度浮点类型double变量height
2.默认情况下,编译器假定浮点型常量是double类型的精度
例: float num = 4.0*2.0;
注: 4.0和2.0被储存为64位的double类型,使用双精度进行运算,然后将乘积截断成float类型的宽度
在浮点数后面加上f或F后缀可覆盖默认设置,编译器会将浮点型常量看作float类型(如20.1f和8.1F)
3.打印float类型变量和double类型变量
printf()函数使用%f转换说明打印十进制计数法的float和double类型浮点数,用%e打印指数计数法的浮点数
例 : float num = 5;
double sum = 714.8;
printf("num = %f, num = %e\n", num,num);
printf("sum = %f, sum = %e", sum,sum);
打印结果为: num = 5.000000, num = 5.000000e+00
sum = 714.800000, sum = 7.148000e+02
六、复数和虚数类型
C语言的三种复数类型: float _Complex、double _Complex和long double _Complex
例: float _Complex类型的变量应包含两个float类型的值,分别表示复数的实部和虚部
C语言的三种虚数类型: float _Imaginary、double _Imaginary和long double _Imaginary
注: 如果包含complex.h头文件,可用complex代替_Complex,用imaginary代替_Imaginary,用I代替-1的平方根
6.声明简单变量
(1).选择需要的类型
(2).使用有效的字符给变量起一个变量名
(3).按以下格式进行声明
类型说明符 变量名; //类型说明符由一个或多个关键字组成
例: int age;
(4).可以同时声明相同类型的多个变量,用逗号分隔各变量名
例: int month,hour,day;
(5).在声明的同时还可以初始化变量
例: float num = 3.14f;
注: 把一个类型的数值初始化给不同类型的变量时,编译器会把值转换成与变量匹配的类型(导致部分数据丢失)
例: int score = 99.98; //score的值为12,编译器丢弃小数部分
float PI = 3.1415926536; //float类型只保证小数点后六位的精度,所以PI = 3.141592
7.类型大小
sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小
C99和C11提供%zd转换说明匹配sizeof的返回类型
例: printf("int类型: %zd字节\n", sizeof(int)); //打印结果 4字节
printf("short类型: %zd字节\n", sizeof(short)); //打印结果 2字节
printf("long类型: %zd字节\n", sizeof(long)); //打印结果 4字节
printf("long long类型: %zd字节\n", sizeof(long long)); //打印结果 8字节
printf("char类型: %zd字节\n", sizeof(char)); //打印结果 1字节
printf("float类型: %zd字节\n", sizeof(float)); //打印结果 4字节
printf("double类型: %zd字节\n", sizeof(double)); //打印结果 8字节
8.参数和陷阱
(1).程序员要负责确保转换说明的数量、类型与后面参数的数量、类型相匹配
(2).C语言通过函数原型机制检查函数调用时参数的个数和类型是否正确
(3).函数原型检查机制对printf()和scanf()不起作用(两个函数的参数个数可变)
例: int num = 4;
int sum = 5;
float PI = 3.14f;
float score = 60.1f;
printf("%d\n", num, sum); //参数太多
printf("%d %d %d\n", num); //参数太少
printf("%d %d\n", PI, score); //参数不匹配
打印结果为: 4
4 0 0
1610612736 1074339512
注: 用%d显示float类型的值,其值不会被转换成int类型
在不同的平台下,缺少参数或参数类型不匹配导致的结果不同
所有编译器都能顺利编译并运行该程序,但其中大部分会给出警告
9.刷新输出
printf()语句把输出发送到一个叫作缓冲区的中间存储区域,然后缓冲区中的内容在不断被发送到屏幕上
当缓冲区满、遇到换行字符或需要输入的时候,从缓冲区把数据发送到屏幕或文件被称为刷新缓冲区