第三章
C语言的数据类型、运算符与表达式
3.1 C语言的数据类型数据与操作是构成程序的两个要素。
操作就是对数据进行的加工,最基本的操作是运算。
C语言的数据类型:
数据类型数值类型 整型实型整型 (int)
长整型 (long int)
单精度型 (float)
双精度型 (double)字符类型 (char)
数组类型结构体类型 (struct)
共用体类型 (union)
枚举类型 (enum)
基本类型构造类型指针类型空类型在程序中对用到的所有数据都必须制定其数据类型
3,1,2常量和变量常量示例
#define PRICE 30
#define NUM 12
void main()
{
...,..
total = NUM * PRICE;
total2 = 84 * PRICE;
printf("total=%d",total);
...,..
} 不会被替换常量符号常量
程序中 # define为宏定义,它的一般形式为:
#define 标识符 字符串作用:用一个指定的标识符来代表一个字符串,这个标识符称为符号常量。
宏定义不能在行末加分号
宏定义通常写在文件开头、函数之前
符号常量名习惯上用大写
使用符号常量的好处是:
1,含意清楚
2,一改全改
3.1.2 变量变量:程序中可改变的量,有名字,占一定的存储单元
1、变量必须先定义后使用
1> 如何定义?
一般形式:类型标识符 变量名如,char c1,c2; int a,i;
float ave; double mul;
2>为何定义变量?
可节省存储空间,加快运行速度可便于检查该变量进行的运算是否合法
2、区分不同的变量 ——使用变量标识符(变量名字)
标识符:用来表示变量、常量、函数等的名字的有效序列,只能由字母、数字或者下划线三种字符构成,且第一个字符必须为字母或下划线,长度一般不超过 8个。
a
-347634
a 变量名存储单元 (地址 )
变量值例:请找出正确的 标识符。
dgh2_ _gjljk 34gf hk.c float j-1 _1a2
正确,dgh2_ _gjljk _1a2
1,C语言中大小写有区别如,CHINA 和 china
average,AVERAGE,Average
2、选择变量应做到,望文生义,
如,average 即表示平均数注意
3,c保留字不能作为标识符如,int char if else for
三种形式十进制整型常量八进制整型常量十六进制整型常量以非 0数字开头 67,450
以 0开头 012 064
以 0x开头 0x1a
如:十进制 八进制 十六进制
9 011 0x9
34 042 0x22
请大家自己写出,23的八进制和十六进制表示:
八进制,027;十六进制,0X17
3.1.3 整型数据一,整型常量常量的类型后缀 (Suffix)
l,L 表示常量是一个长整型
u,U 表示常量是一个无符号整型数两种后缀可以一起使用
123l 长整型常数 123
456U 无符号整型常数 456
789ul 无符号长整型常数 789
101Lu 无符号长整型常数 101
1、整型数据在内存中是以二进制的形式存放的,在 turbo C中,
整型数据占两个字节如,int i ;
i=10;
10i 00000000 00001010
上学期我们学过,计算机内的数值数据是以补码表示的。
根据补码定义,负数 x 的补码用 2n - |x| 来表示,n为机器字长。
二、整型变量设 n=8,则有:
【 -1】 补 =28-1=1111,1111
【 -2】 补 =28-2=1111,1110
【 -3】 补 =28-3=1111,1101

【 -127】 补 =28-127=1000,0001
【 -128】 补 =28-128=1000,0000
在 turbo c中,n为 16,则 【 -1】 补 =216-1=1111,1111,1111,1111
【 -2】 补 =216-2=1111,1111,1111,1110
整型数据在内存中的存放方式二进制形式举例,int i=50; /*int类型占 2字节 */
补码 (Complement)
正数:与原码一致,首位为 0
负数:绝对值取反加一,首位为 1
零:各位全为 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0
高地址字节 低地址字节补码举例举例,int i=-50; /* int类型占 2字节 */
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0
1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 1
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
50的原码
-50的补码取反加一有符号数与无符号数举例
void main()
{
int i;
unsigned j;
i=j=-50;
i=i/2; /*-25*/
j=j/2; /*32743*/
printf("%d %u\n",i,j);
}
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
-50的补码 (65486)
i,j
/ 2
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
i/2-25的补码
j/232743的补码 /原码
2、整型变量的分类
[signed] int
范围,-215 ~~ ( 215-1)即 -32768---32767
unsigned int
范围,0 ~~ ( 216-1) 即 0----65535
long [int]
范围,-231 ~ ~ (231-1)
unsigned long [int]
范围,0 ~~ ( 232-1)
1000000000000000 0111111111111111
0000000000000000 1111111111111111
10000000000000000000000000000000 01111111111111111111111111111111
00000000000000000000000000000000 11111111111111111111111111111111
3、整型变量的定义
int a,b;
unsigned c,d;
long e,f;
1111111111111110
1000000000000000
有符号
-2
无符号
65534
011111111111111132767
-32768
例,-2 的 16位补码表示:
0000000000000010
1111111111111101
4、整型数据可能会溢出如,int a,b;
a=32767;
b=a+1=?
提示:要表示绝对值大于 32767
的整数,请定义无符号整型类型
unsigned int 或长整型类型 long。
两种表示法定点表示指数表示
(浮点表示 ) 3.14e1 或 0.314E2
31.4 21,3.0
3.14× 101 或 0.314× 102
再如,451.23 表示成浮点形式,4.5123e2
注:规范化的指数形式:字母 e之前必须有一个非零的数字( -10.0,0.0)( 0.0,10.0),且
e后面的指数必须为整数。如,1e3,5.665e+3
-3.4221e-4
而 e-5,3.1e2.5,e6都是不合法的指数形式。
3.1.4 实型数据一、实型常量的表示方法二、实型变量
1)实型数据在内存中的存放形式实型数据一般在内存中占 4个字节( 32位),其中包括数符、指数、小数
1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0
指数部分 e 小数部分 f符号 s
类 型 长度 (bit) 有效数字 绝对值范围
float 32 6~7 10-37~1038
double 64 15~16 10-307~10308
long double 128 18~19 10-4931~104932
三,实型常量的类型许多编译系统都将实型常量作为双精度数来处理。
2) 实型变量的分类
es fv 2).1()1(
3.1.5 字符型数据
A,?a?,?sd?,?=?,?\?,?9?
请判断下列那些是字符常量?
1,字符常量 由一对单引号括起来的单个字符 。
如:‘ s?,等注,‘’’,?\? 不是字符常量为什么撇号中的字符不能是 ‘ \
转义字符:用 \ 后跟一特殊字母代表一个控制字符
2、转义字符及含义( P.34 表 3.3)
\
控制字符 代表意义
\ n 换行
\ b 退格
\ \,\,字符
\ ’,’”字符
\,,””字符
\ ddd 八进制所代表的字符
\ xhh 十六进制所代表的字符例如:
main( )
{ printf(“abc\b\bd\ne\r\n\\”);
}
abc_abc ab adcadc
_e_e
_\_
字符型数据是用相应的 ASCII代码的二进制形式存放的。 故,它与整型数据的存放形式是一样的。
如:‘ a’的 ASCII码为 97,则它在内存中的存储形式为

3、字符变量一个字符变量只能存放单个字符。
char c1,c2;
......
c1=?a?; c2=?b?;
4、字符变量的存储形式及其用法
0110001001100001c1 c2
这正是整型数据的存储形式 c1=?a?;? c1=97;
例 3.12 字符型数据与整型数据可以通用
main( )
{char c1,c2;
c1=120; c2=121;
printf(“%c % c\n“,c1,c1);
printf(“%d % d\n“,c1,c1);
}
3.13 大小写字母的转换
main( )
{char c1,c2;
int i1,i2;
c1=?A?; c2=?B?;
i1=?A?+32; i2=?B?+32;
printf(“%c的小写是 %c\n“,c1,i1);
printf(“%c的小写是 %c\n“,c2,i2);
}
是字符还是整数,只有在输出时才有意义
5、字符串常量字符串常量是由一对 双引号 括起来的一串字符。
如:,hello”,“a”,
字符与字符串的区别:
1)字符使用单引号,字符串使用双引号
2)字符只能包括一个字符,字符串可包含一个或多个字符
3)字符串必须以,\0”作为结束
4)C语言中没有专门的字符串变量字符串如需存放变量中,需用字符数组来存放双引号不能在字符串中直接使用。
如:要处理字符串,I say:,goodbye!”,
应写成,printf(“I say,\“goodbye!\”,);
字符串常数在机器中存储是,系统自动在字符串的末尾加一个字符串结束标记
,\0“
如:,Hello”
Hello\0
区别:
‘ a?,a”
a
a \0
3.1.6 变量赋初值可以在定义变量的同时对变量作初始化如:
int a;
float f;
char c;
a=3;
f=3.45;
c=?4?;
int a=3;
float f=3.45;
char c=?4?;
int a,b,c=5;?
int a,b,c;
c=5;
int a=b=c=5;?int a=5,b=5,c=5;?
3.1.7 各类数值数据间的混合运算整型、字符型、实型数据之间可以混合运算,但混合运算时,不同类型的数据按照一定的规则先转换为同一类型,然后再运算。
floatdouble
long
unsigned
int char,short低高设有,int i; float f; double d; long e;
10+ ‘a’+ i * f – d / e97 doubledouble double
整个转换过程是由系统自动进行的例:分别显示一个实数的整数部分和小数部分
main()
{
float x,float1;
int inter;
x=1234.124;
inter=(int)x;
float1=x-inte;
printf(“%f %d %f \n”,x,inte,float1);
}
运算结果可以进行强制转换格式:(类型说明符)(表达式)
(float)a (int)(x+y)
f=5.75
f 的结果为 5.75
(int)f
的结果为 5
3,2 C 语言的运算符与表达式
C语言中有 13类运算符:
1.算术运算符,+,-,*,/,%,++,--
2.关系运算符,>,<,==,>=,<=,!=
3.逻辑运算符:!,&&,||
4.位运算符,<<,>>,~,|,^,&
5.赋值运算符,=
6.条件运算符:?:
7.逗号运算符:,
8.指针运算符,*,&
9.求字节数运算符,sizeof
10.强制类型转换运算符:(类型)
11.成分运算符,.,?
12.下标运算符,[ ]
13.其它:如函数调用运算符( )
祥见 p.301 附录 B
对每个运算符应该掌握如下几点:
运算符的 功能运算符的 优先级运算符的 结合性运算结果的 类型运算符所需 运算量的个数及类型
3.2.2 算术运算符表达式算术运算符分别为:
+(求和),?(求差)
*(求积),/(求商),%(求余)
+(取正数),?(取负数)
优先级、结合性、运算量个数第三类为单目运算符,结合方向“自右向左”,优先级最高第一、二类为双目运算符,结合方向“自左向右”,第二类的优先级比第一类高算术表达式结果的类型同类型 的运算量进行运算,结果仍然为该类型不同类型 运算量进行运算,结果类型以数据类型级别高低来定
a+b,(a*2)/c,(x+r)*8-(a+b)/7,sin(x)+cos(y)
0
6.0
0.9
1
1.5
108+2 的结果为
3.5+2.5 的结果为
3/4 的结果为
4.5/5 的结果为
4.5/3 的结果为
4/3 的结果为整型除以整型为结果为整型
double
long
unsigned
int
float
char,short
模运算符 %的运算对象的类型只能为 整型例如,5%2 的结果为 1
2%5 的结果为 2 5%2.5?
x=i++; x=i; i=i+1;
x=++i; i=i+1; x=i;
++i 或 i++ 等价于 i+1? i
--i 或 i-- 等价于 i-1? i
++,分前置、后置运算,即 ++i,i 或 i++,i
前置运算即先做 ++,--运算,再引用变量,
后置运算即先引用变量后做 ++,运算例如,int i=5;则自增、自减运算符 ++,- -
i++,使变量 i 的值加 1,i--:使变量 i 的值减 1
注意:
1,++,的运算对象只能为 变量,不能为常数?5++
2,++,-- 结合方向是右结合的,即从右到左如,int i=3; -i++? -(i++)
而若 i =3,printf(“%d”,-i++); 的输出应是,-3,i 的结果为 4;
例 3.22:
main()
{ int i=8;
printf("%d ",++i);
printf("%d ",--i);
printf("%d ",i++);
printf(“%d,,i--);
printf("%d ",-i++);
printf("%d \n",-i--);
}
9 8 8 9 -8 -9
结果:
例 3.23:
main()
{ int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d %d %d %d\n",p,q,i,j);
} 15 24 8 8
结果:
例 3.24:
main()
{ int x=100;
printf("%d,%d,%d,%d\n",x++,x,--x,x);
}
结果:
99,99,99,100
课堂练习,
设整型变量 n1,n2,其值均为 3,执行,n2=n1++; n2++; ++n1;”后,
n1的值是,n2的值是 。
A) 3 B) 4 C) 5 D) 6
A) 3 B) 4 C) 5 D) 6
n1 n2
3 3
n2=n1
n1=n1+1
34n2=n2+1
4n1=n1+1 5
C B
3.2.3 赋值运算符和赋值表达式
1、赋值运算符为,=
赋值表达式就是由赋值运算符将变量和表达式连接起来的一个式子。其格式为,变量 =表达式 如,x=a+b;
a+b=12;
y=13;
x-y=z
对错对错
2、赋值表达式的类型转换:
1,将实数赋给整型变量:舍弃小数
2,将整数赋给实型变量:小数点后补 0,数值不变
3,将 double 数据?float 变量:截取前七位有效数字
4,将 char 数据?整型变量:
unsigned char:低 8位赋值,高 8位补 0,
signed char:低 8位赋值,高 8位按符号位扩展,
5,将整型数据?char 型变量:低 8位赋值,高 8位截断例,3.26 赋值运算的类型转换
main()
{ int a,b=322;
float x,y=8.88; char c1=?k?,c2;
a=y;x=b;a=c1;c2=b;
printf(“%d,%f,%d,%c”,a,x,a,c2);
}
结果,107,322.000000,107,B
a+=b;
a=a? b;
a*=b+7; a=a*(b+7);
a/=b; a=a/b;
a%=b; a=a%b;
a%=b+c; a=a%( b+c);
a-=b;
a=a+b;
3、复合赋值运算
+=,?=,*=,/=,%= 等课堂练习,
整型变量a,b,c分别为2,3,4,运算表达式
,a *=16+(b ++)- (++c )”后,a的值是,b的值是,
c的值是 。
a b
2 3
c=c+1
a*=16+b-c
428b=b+1
28 4
c
5
4
5
例 3.28:
设整型变量 n的值为 2,执行语句,n+= n-= n* n;”后,
n的值是 。
A) 0 B) 4 C) - 4 D) 2
n
2
n - = n* n
n=2-2* 2
-2n + = n
n=(-2)+(-2) -4
C
3.2.4 逗号运算符和逗号表达式
1、逗号运算符,,
逗号表达式就是由逗号运算符将若干个表达式隔开的式子,
其一般形式为,表达式 1,表达式 2
例如,(x=5,x+8),(a=3*5,a*4)
逗号表达式的结果是 最后一个表达式的结果运算顺序 从左向右
13
60
逗号表达式的一般形式可以扩展为:
表达式 1,表达式 2,…...,表达式 n
其结果为 表达式 n的结果
(x=5,x+8) 的结果是
(a=3*5,a*4)的结果是课堂练习,
执行语句,x=(a=3,b=a- -)”后,x,a,b的值依次为 。
A) 3,3,2 B) 3,2,2 C) 3,2,3 D) 2,3,2
x = ( a=3,b=a- -);
x a b
3
3
a=3
b=a
a=a-1 32
33
x=3
3
C
课堂练习,
执行语句,f=(3.0,4.0,5.0),(2.0,1.0,0.0);”,
单精度变量 f的值是 。
A) 3.0 B) 5.0 C) 2.0 D) 0.0
f=(3.0,4.0,5.0),(2.0,1.0,0.0);(2.0,1.0,0.0);
赋值运算的优先级高于逗号运算的优先级
f=5.0,0.0 ;
表达式的值为,0.0
f的值为,5.0
3.2.5 关系运算符和关系表达式一、关系运算符
>,>=,<,<=,= =,!=
关系运算符均为双目运算
>,>=,<,<=优先级相同,高于 ==,!=运算符高 -----------?低算术运算符? 关系运算符? 赋值运算符二,关系表达式,用关系运算符将两个表达式连接起来的式子关系表达式的结果为,真,或,假,。
在 C语言中用 1表示,真,,用 0表示,假,
即关系表达式的结果 非 0 即 1
例如,int a=3,b=2,c=1; 则
a>b 的结果为
d=a>b 的结果为
b+c<a 的结果为
a>b==c 的结果为
f=a>b>c 的结果为
1
1
0
1
0
4>x>3 的结果为 0
3.2.6 逻辑运算符和逻辑表达式一、逻辑运算符及其优先次序
C语言提供了三种逻辑运算符:
! (逻辑非)
&& (逻辑与)
|| (逻辑或)
高低
! (逻辑非)是 单目 运算符,优先级最高
&& (逻辑与),|| (逻辑或)是双目运算符,优先级高于赋值运算符,低于关系运算符
逻辑表达式就是用逻辑运算符将逻辑量连接起来的式子
逻辑表达式的结果为 1(真)或 0(假)
! (单目 )?算术运算符?关系运算符?&&?||?赋值运算高高低低高逻辑运算的真值表
0 0
0 1
1 0
1 1
p q !p p&&q p||q
1
1
0
0
0
0
0
1
0
1
1
1
'0'&&'r' 的结果为
5>4>3.2的结果为 1对吗?
错,5>4?1,1>3,2?0
6==6==6的结果为? 0
1
非 0
非 0
非 0
非 0
二、逻辑表达式
a=4,则 !a?0
a=4,b=5 则 a&&b?1
a=4,b=5 则 a||b?1
a=4,b=5 则 !a&&b?0
a=4,b=5 则 !a||b?1
4&&0||2?1
5>5&&2||8<4 -! 00 || 0
C语言中,运算对象不但可以是 0和 1,0和非 0的整数,也可以是 任何类型 的数据。最后判断一个量的真假时以 0作为 "假 ",非 0
作为 "真 "
课堂练习 求下列逻辑表达式的值(设 a=3,b=4,c=5)
( 1) a+b> c && b== c
7 5 4 5
1 0
0
( 2) !(a>b) &&! c ||b+c/2
0 5 4
1 6
0
2
0
1根据下列描述写出 C语言表达式判断某数能否同时被 3,7,11整除(该数为 num)
能被 11整除能被 3整除 能被 7整除且 且
num%3==0 num%7==0 num%11==0&& &&
C语言表达式为,
num%3==0&&num%7==0&&num%11==0
若逻辑运算符、关系运算符、算术运算符同时出现在一个表达式中,优先级别是:
! (单目 )?算术运算符?关系运算符?&&? ||
注意:
在逻辑表达式求值过程中,并不是所有的逻辑运算都执行,
只是在必须执行下一个逻辑运算才能求出表达式的解时才执行。
a&&b&&c 若 a为“假”,则不再判断 b和 c
a||b||c 若 a为“真”,则不再判断 b和 c
例如,
当 a=1,b=2,c=3,d=4,m=1,n=1时,(m=a>b)&&(n=c>d)
执行后,m和 n的值分别为 0和 1,表达式的值为 0。
例,3.34
main()
{ char c='k';
int i=1,j=2,k=3;
float x=3e+5,y=0.85;
printf("%d,%d\n",!x*!y,!!!x);
printf("%d,%d\n",x||i&&j-3,i<j&&x<y);
printf("%d,%d\n",i==5&&c&&(j=8),x+y||i+j+k);
}
结果:
0,0
1,0
0,1
还要注意区别 = 与 = =,
设 x=3,求出下列两个表达式的值及 x 的值。
1) x=0;
2) x= = 0;
表达式的值为 0,x的值为 0
表达式的值为 0,x的值为 3
练习,将下列代数表达式转化成 C语言表达式
2
* 2vm
))()(( csbsass
x7co s30s i n21 。
2
xx ee
a
cb

8
5
1.0/2*sin(3.14/6)*cos(7*x)
sqrt(s*(s-a)*(s-b)*(s-c))
(exp(x)-exp(-x))/2
m*v*v/2
(5-b+c)/(8+a)
作业,
3.2 3.3 3.5 3,7
3.9 3.10
验证 3.2:
main()
{
int x=21003;
printf("%#o,%#x\n",x,x);
}
作业 p,54 3.10 解答,
已知 int a=12,n=5;求下列表达式的值
( 1) a+=a
a=a+a
a=12+12
a=24
( 3) a*=a+3
a=a*( a+3)
a=12*( 12+3)
a=180
( 4) a/=a+a
a=a/( a+a)
a=12/( 12+12)
a=0
( 5) a%=n%=2
a%=( n=n%2)
a%=1
a=0
( 5) a+=a-=a*a a+=( a=a-a*a)
a+=( a=-132) a=a+( -132)
a=( -132) +( -132) a=-264
( 6) a+=a-=a*=a a+=(a=a-(a=a*a))
a+=(a=a-(a=144)) a=a+(a=144-144)
a=a+(a=0) a=0