一、数据类型
1、概念
(1)标识符
1.定义:用来标记常量、变量、函数及文件名字的字符序列。
2.构成规则:只能由数字、字母、下划线三部分组成,且不能以数字开头,并且严格区别大小写,不能定义为系统中存在的关键字。
(2)关键字
c语言中具有特定含义、专门用作语言特定成分的一类标识符
注:在C语言中,所有的关键字都有固定的意义,不能用作其它,且所有的关键字都必须小写
(3)c的数据类型
数据是操作的对象,数据类型是指数据的内在表现形式(代码、存储、运算)
(4)常量和变量
1. 常量
【1】常量:在程序运行过程中,其值不能被改变的量
常量区分为不同类型(表示形式),如:12、1.0、‘a’
【2】符号常量:用一个标识符代表的一个常量
定义方法:#define 标识符 常量
#define PRICE 30
#include <stdio.h> void main() { int num,total; num = 10; total = num * PRICE; printf("total = %d",total); }
2. 变量
【1】变量:其值是可以改变的量,它用标识符(变量名)来表示,在内存中占据一定的存储单元
变量的定义方法: 类型符 标识符
注意事项:<1>见名知意 <2>先定义后使用 <3>习惯上,符号常量名用大写,变量名用小写,以示区别
【2】变量赋初值
变量先定义,后使用,一般放在函数开头
变量初始化:可以在定义时赋初值
2、整型数据
(1)整型常量
1. 各种进制的整数表示方法
十进制整数:由数字0~9和正负号表示. 如 123,-456,0
八进制整数:由数字0开头,后跟数字0~7表示. 如 0123,011
十六进制整数:由0x开头,后跟0~9,a~f,A~F表示. 如 0x123,0xff
2. 整型常量的类型
【1】整型常量的值在-32768~+32767范围内,编译器认为是int类型
【2】整型常量的值超过上述范围,而在-2147483648 ~ +2147483647范围内,编译器认为是long类型
【3】当系统定义short int与int占内存长度相同,则两种类型常量均可以赋给 int和short int型变量
【4】在整型常量后面加大写L或小写l,则告诉编译器,把该整型常量作为long类型处理。例:123L、0L
【5】在整型常量后面加u,则按无符号整型方式存放,负数转换成补码再按无符号整型方式存放。
(2)整型变量
1. 整型数据在内存中的存放形式以二进制的补码表示,每一个整型变量在内存中占2个字节
【1】内存以字节为单元组成,每个字节有一个地址,一个字节一般由8个二进制位组成,每个二进位的值是0或1。
【2】数值的表示方法——原码、反码和补码
原码:最高位为符号位,其余各位为数值本身的绝对值
反码: 正数:反码与原码相同
负数:符号位为1,其余位对原码取反
补码: 正数:原码、反码、补码相同
负数:最高位为1,其余位为原码取反,再对整个数加1
负数补码转换成十进制数:最高位不动,其余位取反加1
补码:11111001 取反:10000110 加1: 10000111=-7
补:整型数据的溢出
此情况称为“溢出”,运行时不报错,编程时要注意
2. 整型变量的分类
补:整数类型和取值范围
int 16位 -32768~32767
short int 16位 -32768~32767
long int 32位 -2147483648~2147483647
unsigned int 16位 0~65535
unsigned short int 16位 0~65535
unsigned long int 32位 0~4294967295
3. 整型变量的定义
int a,b; long num,i,j; unsigned short c,d;
#include <stdio.h> void main() { int a,b,c,d; unsigned u; a = 12; b = -24; u = 10; c = a + u; d = b + u; printf("a+u=%d , b+u=%d\n",c,d); }
3、实型(浮点型)数据
(1)实型常量
1. 浮点数(float)又称为实数(real),有两种表示形式:
【1】十进制小数形式:必须有小数点 如 0.123 、.123 、123.0 、0.0 、123.
【2】指数形式:必须有e或E,e前e后必须有数字,且e后必须是整数 如 123.456e0、12.3456e1 、1.23456e2 、 0.123456e3 、0.0123456e4 等
【3】类型:缺省 double
后缀 f 或 F --> 为 float 型 ; 后缀 l 或 L --> 为 long double 型
2. 浮点型常量的类型
浮点型常量一般按双精度64位处理,数后加 F 或 f 按单精度 ,浮点型常量不分 float 和 double。
(2)实型变量(取值范围与值的精度与机器有关)
单精度(float型):占4个字节,7位有效数字 (3.4e-38~3.4e+38)
双精度(double型):占8个字节,15~16位有效数字 (1.7e-308~1.7e+308)
long double型:占10个字节,15~16位有效数字 (3.4e-4932~1.1e+4932)
float x,y; (指定x、y为单精度浮点型变量) double z; (指定z为双精度浮点型变量) long double t; (指定t为长双精度浮点型变量)
(3)实型数据的舍入误差
1. 浮点型数据在内存中的存放形式
浮点型数据在内存中占4个字节(32位),在内存中分成3部分,指数为2的幂次
2. 数据超过有效位数,则被舍去,故可能产生误差。要避免一个很大的数与一个很小的数加减
#include <stdio.h> void main( ) { float a , b; a= 123456.789e5; b= a+20; printf("%f \n",b); //12345678848.000000 }
注:舍入误差使1.0/3*3 的结果并不等于1 !
4、字符型数据
(1)字符常量
1. 概念
【1】定义:用单引号括起来的单个字符或转义字符(如 ‘a’ ‘A’ ‘\n’ ‘\t ’ )
【2】字符常量的值:该字符的ASCII码值(如 ‘a’——97 ,‘A’——65 ‘\n’——10, ‘\t’——9)
【3】定义格式:char 变量名 = 值
char ch=65 与 char ch=‘A’ 与char=‘\101’是等效的
2. 转义字符:反斜线后面跟一个字符或一个代码值表示,特殊的字符常量,它们都以 ‘\’开头(代表一个字符)
#include <stdio.h> void main( ) { printf(“ ab c\t de\rf\tg\n”); printf(“h\ti\b\bj k”); } /* 显示结果: f gde h j k */
(2)字符变量
1. 字符变量用来存放字符,且只能存放一个字符,占用一个字节。
2. 定义方法: char c1,c2; 赋值方法:c1=‘a’ ; c2=‘\101’ (A); c3 = 0xff (255); c4=\'\377\'(255);
(3)字符数据存储
1. 以二进制存放字符的ASCII码值(0~255整数),与整数的存储形式类似
#include <stdio.h> void main( ) { char c1,c2 ; c1=97 ;c2=98 ; printf(“%c %c \n",c1,c2); //a b c1=\'a\' ;c2=\'b\' ; printf(“%c %c \n",c1,c2); //a b }
2. 字符数据与整型数据可以相互赋值
3. 字符数据可以以字符或整数形式输出
#include <stdio.h> void main( ) { int i; char c; i = \'a\'; c = 97; printf(“%c %d \n",i,i); // a 97 printf(“%c %d \n",c,c); // a 97 }
补:
#include <stdio.h> void main( ) { char c; c = \'\376\'; printf(“%c ,%d \n",c,c); // () 254 } #include <stdio.h> void main( ) { unsigned char c; c = \'\376\'; printf(“%c ,%d \n",c,c); // () -2 }
(3)字符串常量
1. 定义:用一对双引号(“ ”)括起来的字符序列。如:“How do you do” , “CHINA” , “a” , “$123.45”
2. 存储:每个字符串尾自动加一个 ‘\0’ 作为字符串结束标志
字符串“hello”在内存中
空串 “”
没有字符串变量, 只能用字符数组存放
5、各类数值型数据间的混合运算
整型、实型、字符型数据间可以混合运算
(1)什么情况下发生自动转换
1. 运算转换------不同类型数据混合运算时
2. 赋值转换------把一个值赋给与其类型不同的变量时
3. 输出转换------输出时转换成指定的输出格式
4.函数调用转换------实参与形参类型不一致时转换
(2)运算转换规则:不同类型数据运算时先自动转换成同一类型
(3)强制转换
一般形式:(类型名)(表达式)
例:(int)(x+y), (int)x+y, (double)(3/2) ,(int)3.6
说明:强制转换得到所需类型的中间变量, 原变量类型不变
#include <stdio> main() { float x; int i; x=3.6; i=(int)x; //表达式仅一个变量时,括号可以省略 printf(“x=%f,i=%d”,x,i); } //结果:x=3.600000,i=3
注:较高类型向较低类型转换时可能发生精度损失问题
二、运算符和表达式
1、c运算符(34种)
2、算术运算符和算术表达式
(1)基本算术运算符: + - * / %
说明:【1】 “-”可为单目运算符时,右结合性
【2】两整数相除,结果为整数
【3】%要求两侧均为整型数据
【4】+ - * / 运算的两个数中有一个数为实数,结果是double型
(2)自增、自减运算符++ --
前置 ++i, - -i (先执行i+1或i-1,再使用i值)
后置 i++,i- - (先使用i值,再执行i+1或i-1)
注意:【1】自增、自减运算符只能用于变量,而不能用于常量或表达式
【2】++ 和 - - 的优先级高于算数运算符,结合方向“自右向左”
如:-i++ 相当于 - (i++)
3、赋值运算符和赋值表达式
(1)简单赋值运算符" = "
用法: 变量标识符 = 表达式
作用:将一个数据(常量或表达式)赋给一个变量 ,左侧必须是变量,不能是常量或表达式
(2)类型转换
赋值转换规则:使赋值号右边表达式值自动转换成其左边变量的类型
【1】实型数据(包括单、双精度)赋给整型变量时,舍弃实数的小数部分
【2】整型数据赋给单、双精度变量时,数值不变,但以浮点数形式存储到变量中
【3】长度相同的有符号与无符号整型数间,原样赋值,但数值有时会有变化
#include <stdio> void main() { unsigned a; int b = -1; a = b; printf(“%d , %u \n”,b,a); //b=-1 a=65535 a = 65534u; b = a; printf(“%d , %u \n”,b,a); //b=-2 a=65534 }
【4】char、int、long 等类型的转换
1)“短”数据赋给“长”变量
符号扩展:若最高位位1(负数),则变量高字节位补1;反之,补0。
2)“长”数据赋给“短”变量
只将数据的低字节位原封不动送到变量中(数据有可能有差错)
(3)复合赋值运算符
在赋值符“ = ”之前加上其它运算符,构成复合赋值运算符
种类:+= -= *= /= %= 《= 》= &= ^= |=
(4)赋值表达式
形式:<变量> <赋值运算符> <表达式>
赋值表达式的值与变量值相等,且可嵌套
表达式中允许出现运算符号、变量、数值、函数
4、逗号运算符和逗号表达式
形式:表达式1,表达式2,……表达式i
作用:用于连接表达式,如:3+5,3+6
一个逗号表达式又可以与另一个表达式组成一个新的逗号表达式
逗号运算符是所有运算符中级别最低的
注意:并不是任何地方出现的逗号都是逗号运算符,如:printf(" %d , %d ,%d " ,a,b,c)
a=3*5,a*4 //a=15,表达式值60 a=3*5,a*4,a+5 //a=15,表达式值20 x=(a=3,6*3) //赋值表达式,表达式值18,x=18 x=a=3,6*a //逗号表达式,表达式值18,x=3 a=1;b=2;c=3; printf(“%d,%d,%d”,a,b,c); //1,2,3 printf(“%d,%d,%d”,(a,b,c),b,c); //3,2,3
5、关系运算符和关系表达式
“关系运算”即“比较运算,是对两个值进行比较,比较的结果是得到真假两种值。
(1)关系运算符
【1】关系运算符及其优先次序
1—>种类(6种关系运算符): <= == >= > !=
2—>结合方向:自左向右
3—>优先级别:算术运算符 > 关系运算符 > 赋值运算符
< (小于) 、<= (小于等于) 、 > (大于) 、 > = (大于等于) ——> 优先级6(高)
= = (等于) 、 ! = (不等于) ——> 优先级7(低)
(2)关系表达式:用关系运算符将两个表达式连接起来的式子
a>b , (a+b)>(b+c) , 5==3
【1】关系表达式的值:是逻辑值“真”或“假”,用1和0表示
int a=3,b=2,c=1,d,f; a>b //表达式值1 (a>b)==c //表达式值1 b+c<a //表达式值0 d=a>b // d = 1 f=a>b>c // f = 1
【2】关系运算注意事项
//>结合方向自左至右 5>2>7>8 // 0 int i=1, j=7,a; a=i+(j%4!=0); // a=2 // 用ASCII值比较 ‘a’>0 // 结果为1 ‘A’>100 // 结果为0
应避免对实数作相等或不等于0的判断,如 1.0/3.0*3.0==1.0 可改写为:fabs(1.0/3.0*3.0-1.0)<1e-6
注意区分“ = ”与“ = = ”
int a = 0,b = 1; if(a = b) printf(“a equal to b”); else printf(“a not equal to b”);
6、逻辑运算符和逻辑表达式
(1)逻辑运算符: C语言提供3种逻辑运算符
“!”是单目运算符 、 “&&”和“ ||”是双目运算符
【1】逻辑运算真值表
【2】逻辑运算符的优先次序
1—>优先次序:!(非) > &&(与) > ||(或)
2—>结合方向:从右向左 从左向右 从左向右
(2)逻辑表达式: 用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。
【1】C语言中, 运算量 0表示“假”,运算结果 0表示“假”, 非0表示“真”, 1表示“真”。
a=4;b=5; !a //0 a&&b //1 a||b //1 5>3&&2||8<4-!0 //1 ‘c’&&‘d’ //1 !a||b //1 4&&0||2 //1
【2】逻辑运算中的注意点:
短路特性:逻辑表达式求解时,并非所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。
a&&b&&c //只在a为真时,才判别b的值;只在a、b都为真时,才判别 c的值 a||b||c //只在a为假时,才判别b的值;只在a、b都为假时,才判别 c的值
a=1;b=2;c=3;d=4;m=1;n=1; (m=a>b)&&(n=c>d) //结果 m=0,n=1
【3】复杂逻辑条件的表述
//判别闰年的条件(int year): //能被4整除: year%4==0 //能被4整除但不能被100整除: (year%4==0)&&(year%100!=0) //能被400整除: year%400==0 //综合起来: ((year%4==0)&&(year%100!=0))||year%400==0 /优化语句: (year%4==0&&year%100!=0)||year%400==0
7、条件运算符(表达式1 ? 表达式2 : 表达式3)
条件运算符是 C 语言中唯一的三目运算符
if (a>b) max=a; else max=b; //等价于 max=(a>b)? a:b;
条件运算符说明:条件运算符可嵌套,优先级: 13,结合方向自右向左
表达式1?表达式2:表达式3 类型可以不同,表达式值取表达式2和表达式3中较高的类型
x>0?1:(x<0?-1:0)
x?‘a’:‘b’ //x=0,表达式值为‘b’; x≠0,表达式值为‘a’ x>y?1:1.5 //x>y ,值为1.0; x<y ,值为1.5