第 3章 数据类型、运算符与表达式
数据类型
常量与变量
整型、浮点型、字符型
变量赋初值
不同类型数据间的转换
算术运算符和算术表达式
赋值运算符和赋值表达式
逗号运算符和逗号表达式
3.1 数据类型
C
数据类型指针类型空类型 void
定义类型 typedef
构造类型枚举类型 enum
数组结构体 struct
共用体 union
基本类型字符类型 char
整 型实型 单精度型 float双精度型 double
短整型 short
长整型 long
整型 int
数据类型决定:
1,数据占内存字节数
2,数据取值范围
3,其上可进行的操作
基本数据类型类型 符号 关键字 数的表示范围所占位数整型字符型实型有无
(signed) int 16 -32768~32767
(signed) short 16 -32768~32767
(signed) long 32 -2147483648~2147483647
16unsigned int 0~65535
32 0~4294967295unsigned long
unsigned short 16 0~65535
有 float 32 3.4e-38~3.4e38
有 double 64 1.7e-308~1.7e308
有 char 8 -128~127
无 unsigned char 8 0~255
说明,数据类型所占字节数随机器硬件不同而不同,上表以 IBM
PC机为例
3.2 常量与变量
标识符 (Idetifier) P39
定义:用来标识变量、常量、函数等的字符序列
组成:
只能由 字母、数字、下划线 组成,且第一个字母必须是字母或下划线
大小写敏感
不能使用关键字讨论:判断下列标识符号合法性
sum Sum M.D.John day Date 3days
student_name #33 lotus_1_2_3 char a>b
above $123 _toDay
.D.J 3da s
c ar
$123
长度,Turbo C中最长 32个字符
命名原则:
见名知意,采用简洁有含义的英文单词(或缩写)
不宜混淆 如 I,1与 l,o与 0
标识符命名实例
stu_name,sum,total,day,count,sort
常量和符号常量( P37)
在程序运行过程中,其值不能改变的量称为 常量 (Constant)
常量可为任意数据类型
字面常量(直接常量)
整型,12,0,-3
实型,4.6,-1.23
字符型,’ a’、’ d’
字符串常量:” Hello”、” Good Morning!”
符号常量:标识符代表常量
定义格式,#define <符号常量名 > <常量 >
符号常量定义举例
#define PI 3.1415926
#define STAR ‘*’
说明,符号常量一般使用 大写 英文字母表示,以区别一般用于小写字母表示的变量注意:符号常量不能改变,不能赋值!
STAR = ‘#’
符号常量使用例 符号常量举例
#define PRICE 30
main()
{
int num,total;
num=10;
total=num*PRICE;
printf("total=%d",total);
}
运行结果,total=300
符号常量的使用能给程序员带来哪些好处?
含义清楚;一改全改
变量 (Variable)
其值可以改变的量称为变量
变量也可以为任意数据类型
变量定义的一般格式数据类型 变量 1[,变量 2,…,变量 n];
决定分配字节数和数的表示范围变量定义举例,
int a,b,c;
float data;
变量的使用:作强制定义,“先定义,后使用”
例 1
int student; /* 16bit */
stadent=19; /*Undefined symbol ‘stadent’ in function main*/
例 2
float a,b,c;
c=a%b; /*Illegal us of floating point tio in*/
整型数据 ( Integer)
整型常量形式 表示方式 举例十进制整数 由数字 0~9和正负号表示 123,-456,0
八进制整数 由数字 0开头,后跟数字 0~7表示 0123,011
十六进制整数 由 0x开头,后跟 0~9,a~f,A~F表示 0x123,0Xff
问题:
0123 = ( )10
0x123 = ( )10
0Xff = ( )10
83
291
256
3.3 整型数据整型常量的类型 (P44)
根据其值所在范围确定其数据类型
在整常量后加字母 u或 U,认为它是 unsigned int型
在整常量后加字母 l或 L,认为它是 long int 型常量例 12 与 12L

30000 为 int型
65536 为 long int型例 12 与 12U
整型变量
整型变量在内存中以 二进制补码 的形式存放
根据占用的字节数不同,分为不同类别
整型变量的定义整型变量定义举例,
int a,b;
unsigned short c,d;
long e,f;
#include <stdio.h>
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);
}
运行结果,a+u = 22,b+u = -14
变量的定义一般放在一个函数开头的声明部分
整型数据的溢出 (Overflow)
溢出:数据超出了变量能够存储的范围,造成数据丢失或数值改变等
void main()
{
int a = 32767;
a=a+1; /*32768?*/
}
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1
32767的补码
-32768的补码浮点型常量
表示形式:
十进制数形式,(必须有小数点;整数和小数部分可以省略,但不能同时省略)
指数形式,( e或 E之前必须有数字;指数必须为整数)
十进制数形式实型常量
0.123,.123,123.0,0.0,123.指数形式实型常量
12.3e3,123E2,1.23e4,e-5,
1.2E-3.5,.e3
3.4 浮点型数据
实型数据
实型常量
规范化的指数形式:
即在字母 e(或E )之前的数据部分中,小数点左边有且仅有一位非零的数字。
指数形式实型常量
12.3e3,123E2,1.23e4,
0.123e-3
浮点型常量的类型 ( P47)
浮点型常量一般作为 double型来处理(精确,速度慢)
在数字后加上字母 f或 F,则作为 float型来处理
float a;
a = 111111.111
double a;
a = 111111.111
问题:以下两段程序代码,是否有区别?
实型变量
float,占 4字节,提供 7位有效数字
double:占 8字节,提供 15~16位有效数字
注意舍入误差
#include <stdio.h>
void main()
{
float a,b;
a=123456.789e5;
b=a+20;
printf(“%f %f\n”,a,b); /*12345678848.000000*/
}
字符常量
定义:用 单引号 括起来的单个 普通字符 或 转义字符 。
字符常量的 值,该字符的 ASCII码值
转义字符:反斜线后面跟 一个字符 或 一个代码值 表示如 ‘ a‘?A‘‘?\n‘?\101‘
如 ‘ A?——65,‘ a?——97,
‘ 0?——48,?\n?——10
<
转义字符及其含义:
转义字符 含义
\n
\v
\r
\a
\?
\ddd
\t
\b
\f
\\
\“
\xhh
转义字符 含义换行垂直制表回车响铃单引号
3位 8进制数代表的字符水平制表退格换页反斜线双引号
2位 16进制数代表的字符如 ‘ \101? -----------?A\012? -----------?\n?
\376? -----------\x61? -----------?a?
\60? -----------?0\483? ----------(?)
例,
A?-------?\101?-------?\x41?--------65
例 转义字符举例 (ch2_001.c,ch2_004.c)
main()
{
printf("\101 \x42 C\n");
printf("I say:\"How are you?\"\n");
printf("\\C Program\\\n");
printf("Turbo \'C\'");
}
运行结果,(屏幕显示 )
A B C
Isay:‖How are you?‖
\C Program\
Turbo?C‘
例 main()
{ printf(“Y\b=\n”);
}
运行结果:
屏幕显示,=
打印机输出,¥
注意事项:
单撇号中的字符不能是’或者 \
一个字符占一个字节,存其对应的 ASCII码
思考:’ 9‘和 9的区别
字符型数据可像证书一样在程序中参与相关的运算
a‘ – 32 结果为 65
字符变量
字符变量存放字符 ASCII码
char与 int数据间可进行算术运算例 1 a=?D?; /* a=68; */
x=?A?+5; /* x=65+5; */
s=?!?+?G? /* s=33+71; */
例 2
main()
{
char c1,c2;
c1=97; c2=98;
printf(―%c %d‖,c1,c2);
}
/*ch2_003.c*/
#define PRICE 12.5
main()
{ int num=3;
float total;
char ch1,ch2=?D?;
total=num*PRICE;
ch1=ch2-?A?+?a?;
printf(“total=%f,ch1=%c\n”,total,ch1);
}
宏定义变量定义输出结果运行结果:
total=37.500000,ch1=d
例子
字符串常量
定义:用双引号 (―‖)括起来的字符序列
存储:每个字符串尾 自动 加一个 ‘ \0‘ 作为字符串结束标志
字符常量与字符串常量不同例 字符串,hello” 在内存中 h e l l o \0例 空串,” \0
a \0例 ‘ a’ a,a”
例,char ch;
ch=?A?;
例,char ch;
ch=“A”;
没有 字符串变量,用字符数组存放
变量赋初值
…...
…...
编译程序根据变量定义为其分配指定字节的内存单元地址
int a=1,b=-3,c;
a
b
c
2字节
2字节
2字节地址地址内存
1
-3

随机数如果定义了变量,但是没有对它赋初值,则它的值是一个不确定的数值例
main()
{
int x,y;
printf(―%d,%d‖,x,y);
}
运行结果,64,3129
2.3 不同类型数据间的转换
隐式转换
什么情况下发生
运算 转换 ------不同类型数据混合运算时
赋值转换 ------把一个值赋给与其类型不同的变量时
输出转换 ------输出时转换成指定的输出格式
函数调用转换 ------实参与形参类型不一致时转换
a‘ – 32 int age;
age = 11.1char name=?a‘;printf(“%d\n”,name);
运算转换规则,不同类型数据运算时先 自动 转换成同一类型
double float
long
unsigned
int char,short低高说明,
必定的转换运算对象类型不同时转换
char ch;
int i;
float f;
double d;
ch/i + f*d - (f+i)
int
int
double
double
float
double
double
double
例 1
int
int
double
double
double
double
double
double
10+?a? +i*f - d/l
例 2
int i;
float f;
double d;
long l;
显示转换可以利用强制类型转换将一个表达式转换成所需类型一般形式,(类型名) ( 表达式)
例,(int)(x+y)
(int)x+y
(double)(3/2)
(int)3.6
说明:强制转换得到所需类型的中间变量,原变量类型不变例 main()
{ float x;
int i;
x=3.6;
i=(int)x;
printf(“x=%f,i=%d”,x,i);
}
结果,x=3.600000,i=3
较高类型向较低类型转换时可能发生精度损失问题
2.4 算术运算符和算术表达式
C运算符简介
C
运算符算术运算符,( + - * / % ++ --)
关系运算符,( < <= == > >= !=)
逻辑运算符,( ! && ||)
位 运 算 符:( << >> ~ | ^ &)
赋值运算符,( = 及其扩展)
条件运算符,(?:)
逗号运算符,(,)
指针运算符,( * &)
求 字 节 数:( sizeof)
强制类型转换:(类型)
分量运算符,(,->)
下标运算符,( [])
其它,( ( ) -)
学习运算符应注意
运算符功能
与运算量关系
-要求运算量个数
-要求运算量类型
运算符优先级别
结合方向
结果的类型
基本的算术运算符
+ 加法运算或正值运算符
- 减法运算或负值运算符
* 乘法运算符
/ 除法运算符,求商,两个整数相除结果为整数
% 模运算符,求余,要求两则均为整型数据
3+5,+35-2,-3
3*55/37%4
例 5/2 =
-5/2.0 =
例 5%2 =
-5%2 =
5%-2 =
1%10 =
5%1 =
5.5%2
2
-2.5
1
-1
1
0
(?)
1
取模的余数符号由分子(被除数决定)
算术表达式和运算符的优先级和结合性
算术表达式,用算术运算符和括号将运算对象连接起来的、符合 C语法规则的式子。
求表达式的值:
① 先按运算符的优先级别高低次序执行;
② 再一个运算对象两则的运算赋的优先级别相同,
则按规定的“结合方向”处理。
a*b/c-1.5+‘a‘
a – b * c / d
自增 ++、自减运算符 —
作用:使变量值加 1或减 1
种类:
前置 ++i,--i (先执行 i+1或 i-1,再使用 i值
后置 i++,i-- (先使用 i值,再执行 i+1或 i-1)
例 j=3; k=++j;
j=3; k=j++;
j=3; printf(“%d”,++j);
j=3; printf(“%d”,j++);
a=3;b=5;c=(++a)*b;
a=3;b=5;c=(a++)*b;
/*k=4,j=4*/
/*k=3,j=4*/
/*4*/
/*3*/
/*c=20,a=4*/
/*c=15,a=4*/
注意说明,
只能用于变量,不能用于常量或表达式;
结合方向“自右向左”;
优先级别,- - ++ -- ------> * / % -----> + -
自增(减)运算常用于循环语句中循环变量自动加
(减) 1或指针变量,使指针指向下一个地址
5++ (× ) (a+b)++ (× )
i++ (√ )
例 1解答,-i++? -(i++)
i=3; printf(“%d”,-i++); //-3例 1,-i++i=3; printf(“%d”,-i++);例 2,j+++k; (j++)+k;
有关表达式使用中的问题说明
表达式中包含多个自加、自减运算时,很容易出错例 1,如 i= 3,则 k= i++ 结果,k= 3,i= 4
例 2,如 i= 3,则 (i++) + (i++) + (i++)
结果,9,i= 6
例 3,如 i= 3,则 (++ i) + (++ i) + (++ i)
结果,18,i= 6
i+++j,应如何结合?
调用函数时,实参数地求值顺序,c并无统一规定
C编译在处理时尽可能多地(自左而右)将若干个字符组成一个运算符。所以应该为 (i++)+j
举例:如 i= 3,则 printf(“%d,%d”,i,i++)
解答:
若对参数的求值顺序为 自右而左,打印 4,3 且 i=4;
若对参数的求值顺序为 自左而右,打印 3,3 且 i=4;
2.5 赋值运算符和赋值表达式
简单赋值运算符,=,
作用:将一个 数据 赋给一个 变量常量或表达式 只能是变量,不能是常量或表达式例 3=x-2*y;
a+b=3;
例 a= 3;
a= (a+b)*c
赋值转换规则,使赋值号右边表达式值 自动 转换成其左边变量的类型例 1 float f;
int i;
i=10;
f=i;
则 f=10.0
例 2 int i;
i=2.56; //结果 i=2;
实型数据赋给整型变量 舍弃实数的小数部分整型数据赋给实型变量 补足有效位数字字符型数据赋给整型变量 分别考虑系统将字符处理为无符号的量和带符号的量两种情况带符号的整型赋给 long int型变量 注意符号扩展问题
unsigned int型数据赋给 long int
型变量注意最高位为 1的情况非 unsigned型数据赋给长度相同的 unsigned型变量原样照搬,连同原有的符号位
结合方向,自右向左优先级,14
例,a=b=c=5
a=(b=5)
a=5+(c=6)
a=(b=4)+(c=6)
a=(b=10)/(c=2)
/* 表达式值为 5,a,b,c值为 5 */
/* b=5;a=5 */
/* 表达式值 11,c=6,a=11 */
/* 表达式值 10,a=10,b=4,c=6 */
/* 表达式值 5,a=5,b=10,c=2 */
复合的赋值运算符
+= -= *= /= %=,=,= &= ^= |=
a+=3 a=a+3
x*=y+8 x=x*(y+8)
x%=3 x=x%3
赋值表达式
定义,由赋值运算符将一个变量和一个表达式连接起来的式子,叫赋值表达式。
一般形式,<变量 > <赋值运算符 > <表达式 >
赋值表达式的值 与变量值相等,且可嵌套例,a=12;
a+=a-=a*a /* a=-264 等价于 a=a+(a=a-(a*a))*/
例,int a=2;
a%=4-1;
a+=a*=a-=a*=3; /*a=0 等价于 a=a+(a=a*(a=a-(a=a*3)))*/
2.6 逗号运算符和逗号表达式
形式,表达式 1,表达式 2,…… 表达式 n
结合性,从左向右
优先级,15(最低)
逗号表达式的值,等于表达式 n的值例 1 a=3*5,a*4
a=3*5,a*4,a+5
例 2 x=(a=3,6*3)
x=a=3,6*a
例 3 a=1;b=2;c=3;
printf(“%d,%d,%d”,a,b,c);
printf(“%d,%d,%d”,(a,b,c),b,c);
/* a=15,表达式值 60 */
/* a=15,表达式值 20 */
/* 赋值表达式,表达式值 18,x=18 */
/* 逗号表达式,表达式值 18,x=3 */
/*1,2,3*/
/*3,2,3*/
例,
#include <stdio.h>
main()
{ int x,y=7;
float z=4;
x=(y=y+6,y/z);
printf("x=%d\n",x);
}
运行结果,x=3