Chap 2 基本数据类型和表达式
? 数据类型
– 基本数据类型
? 整型 int
? 实型(浮点型) float double
? 字符型 char
– 构造数据类型
数组、结构、联合、枚举
– 指针类型
– 空类型
? 对数据的操作-运算
运算符和表达式
Chap 2 基本数据类型和表达式
? 常量和变量
? 整数类型
? 实数类型
? 字符类型
? 表达式
? 数据的存储和类型转换
2.1 常量和变量
2.1.1 常量
?常量(常数):数据
123 (整型) 4.56 (实型 ) ’ A’ (字符型 )
?符号常量:用标识符表示的常量数据
?,PI
?,EPS
通常用大写字母
例 2- 1 求球的表面积和体积
# include <stdio.h>
void main( )
{
float r,s,v;
scanf("%f",&r);
s=4.0*3.14*r*r ;
v=4.0/3.0*3.14*r*r*r ;
printf("s=%f,v=%f\n",s,v);
}
s=4.0*3.14159*r*r ;
v=4.0/3.0*3.14159*r*r*r ;
例 2- 2 符号常量
# define PI 3.14
# include <stdio.h>
void main( )
{
float r,s,v;
scanf("%f",&r);
s=4.0*PI*r*r ;
v=4.0/3.0*PI*r*r*r ;
printf("s=%f,v=%f\n",s,v);
}
# define PI 3.14159
2.1.2 变量
C语言中的量
? 常量 (常数):数据
? 符号常量,用标识符表示的常量数据
在程序的运行过程中,其值不能被改变
? 变量,存放数据的 工作单元
在程序的运行过程中,其值可以改变
变量的定义
变量定义的一般形式
类型名 变量表;
变量名:小写字母, 见名知义
类型名:
?整型 int
?实型(浮点型) float double
?字符型 char
变量的定义
int i,j,k; ( 定义 i,j,k为整型变量 )
char c; ( 定义 c为字符型变量 )
float x,y;
double area,length;
变量名代表内存中的一个存储单元
用于存放该变量的值
该存储单元的大小由变量的数据类型决定
变量的定义与使用
变量必须 先 定义,后 使用 。
# include <stdio.h>
void main( )
{
int x,y;
x = 3;
y = x*x ;
printf(“%d”,y ) ;
}
一个变量名只能定义一次 。
变量一般都定义在程序的头上,
不能定义在程序的中间或后面。
变量的使用
变量, 先定义, 后 使用
先赋值, 后引用
# include <stdio.h>
void main( )
{
int x,y;
x = 3;
y = x*x ;
printf(“%d”,y ) ;
}
变量的赋值
? 赋初值:在定义变量时对它赋值
int a = 5,b = 3;
? 赋值表达式:
int a,b;
a = 5;
b=3;
? 输入函数,
scanf(“%d%d”,&a,&b);
2.2 整数类型
2.2.1 整型常量(整数)
三种表现形式
? 十进制整数:正、负号,0- 9,首位不是 0
例,10,123
? 八进制整数:正、负号,0- 7,首位是 0
例,010,0123
? 16进制整数:正、负号,0- 9,a-f,A-F,前缀
是 0x,0X
例,0x10,0x123
123 = 1111011 (B) 二进制
=173 (O) 八进制
=7B (X) 十六进制
int i=0173;
int j=0x7b;
int k=123;
例,16 020 0x10
10 012 0XA
2.2.2 整型变量
int ai,bi,ci,di = 0;
ai = 1;
bi = -27;
ci = 012;
整型变量的值是整数, 它的取值范围有限
最小取值范围 [- 32768,32767]
2.2.3 整型数据的输入输出
printf(格式控制,输出参数 1,...,输出参数 n);
scanf(格式控制,输入参数 1,...,输入参数 n);
格式控制说明 %…
%d,以十进制形式输入, 输出整数
%o,以八进制形式输入, 输出整数
%x,以十六进制形式输入, 输出整数
例 2-3
# include <stdio.h>
void main( )
{
printf("%d,%o,%x\n",10,10,10);
printf("%d,%d,%d\n",10,010,0x10);
printf("%d,%x\n",012,012);
}
运行结果为:
10,12,a
10,8,16
10,a
0……01010
例 2-4
# include <stdio.h>
void main( )
{
int a,b;
scanf("%o%d",&a,&b);
printf("%d%5d\n",a,b);
printf("%x,%d\n",a,b);
}
输入:
17 17
运行结果为:
15 17
f,17
2.3 实型数据
2.3.1 实型 常量 (实数 )
– 浮点表示,0.123 123.4 1.
– 科学计数法,123e4 0.2e-1
2.3.2 实型 变量
– 单精度浮点型
float x,y,z;
– 双精度浮点型
double u,v,w;
4字节存储
8字节存储
数据精度和取值范围
数据精度 取值范围
单精度 七 位有效数字 ± (10-38 - 1038)
双精度 十六 位有效数字 ± (10308 - 10308 )
? 数据 精度 与 取值范围 是两个不同的概念:
float x = 1.23456789;
float y = 123456789;
虽在数据表示范围内,但无法精确表达。
float z = 1.2e55
z的精度要求不高,但数据表示范围超出。
? 并不是所有的实数都能在计算机中精确表示。
? 实型常量的类型都是 double
x=1.234568
y=1.234567e8
2.3.3 实型数据的输入和输出
? 输出 printf( )
float 和 double使用相同的格式控制说明
– %f,以小数形式输出浮点数, 保留 6位小数 。
– %e,以指数形式输出
1 位整数,5位小数 e 3 位指数
例 2-5 实型数据的输出
# include <stdio.h>
void main( )
{
float f = 123.45;
double d = 3.1415926;
printf("%f,%e\n",f,f);
printf("%f,%e\n",d,d);
printf("%5.3f,%5.2f,%.2f\n",d,d,d);
}
一共 5位, 小数 3位, 小数点一位
运行结果为:
123.450000,1.23450e+02
3.141593,3.14159e+00
3.142,3.14,3.14
例 2-6
假定 float的精度为 7位,double的精度为 16位
# include <stdio.h>
void main( )
{
float f;
double d1,d2;
f = 1234567890123.123456;
d1 = 1234567890123.123456;
d2 = 1234567890123.12;
printf("f = %f \n d1 = %f \n d2 = %f \n",f,d1,d2);
}
运行结果为:
f = 1234567954432.000000
d1 = 1234567890123.123540
d2 = 1234567890123.120120
实型数据的输入
scanf( )
– float 和 double使用不同的格式控制说明
– %f和 %e相同
– %f, 以小数或指数形式输入一个单精度浮点数
– %e
– %lf,以小数或指数形式输入一个 双精度 浮点数
– %le
例 2-7
# include <stdio.h>
void main( )
{
float f1;
double d1;
scanf("%f%lf",&f1,&d1);
printf("f1 = %f \n d1 = %f \n",f1,d1);
}
输入:
12 1234567.12345
运行结果为:
f1=12.000000
d1=1234567.123450
2.4 字符类型
2.4.1 字符常量
’ a’ ’A’ ’9’ ’+’ ’$'
ASCII字符集:列出所有可用的字符
每个字符:惟一的次序值 ( ASCII 码 )
'0'-'9'
'A'-'Z'
'a'-'z'
2.4.1 字符常量
– 字符的存储
在内存中, 每个字符占用一个字节, 存储该字符的ASCII码
字符 ASCII码 内存
'A' 65 0100 0001
'B' 66 0100 0010
– 字符的数值特征
字符可以当整数用, ASCII码
'A'+1 =?
2.4.2 字符变量
char c1,c2,c3;
c1='2';
c2='#';
c3='A';

c3=65;
int i;
i=65;

i='A';
整型变量和字符变量的定义和赋值可以互换
【 ASCII码 范围 】
2.4.3 字符型数据输入输出
? scanf( )和 printf( )
%c
char ch;
scanf("%c",&ch);
printf("%c",ch);
? getchar( )和 putchar( )
char ch;
ch=getchar( );
putchar(ch);
输入输出一个字符
例 2-9
# include <stdio.h>
void main( )
{
char ch1,ch2;
ch1=getchar();
ch2=getchar();
putchar(ch1);
putchar('#');
putchar(ch2);
}
运行结果为:
A#b
输入:
Ab
例 2-10
# include <stdio.h>
void main( )
{
char ch1,ch2,ch3;
scanf("%c%c%c",&ch1,&ch2,&ch3);
printf("%c%c%c%c%c",ch1,'#',ch2,'#',ch3);
}
运行结果 1为:
A#b#C
输入 1:
AbC
运行结果 2为:
A# #b
输入 2:
A bC
输入数据包括字符和数值的混合
# include <stdio.h>
void main( )
{
int i;
char c;
float x ;
scanf("%d%c%f",&i,&c,&x );
printf( "%d %c %f",i,c,x );
}
输入,3a1.2
输出,3 a 1.200000
数据之间不能用空格等间隔,
也不需要单引号
例 2-11
已知,'b'的 ASCII码 98
# include <stdio.h>
void main( )
{
printf("%c,%d\n",'b','b');
printf("%c,%d\n",98,98);
printf("%c,%d\n",97,'b'-1);
}
运行结果为:
b,98
b,98
a,97
0110 0010'b'98 'b'98
# include <stdio.h>
void main( )
{
char ch='b';
printf("%c,%d\n",ch,ch);
}
0110 0010
'b'
98
142
62
'b'
98
0142
0x62
printf
'b' %c putchar
98 %d
142 %o
62 %x
scanf
'b' %c getchar
98 %d
142 %o
62 %x
scanf("%c",&ch);
字符运算
? 大小写英文字母转换
'b' - 'a' = 'B' - 'A'
……
'z' - 'a' = 'Z' - 'A'
'm' ?? 'M'
? 数字字符和数字
9 - 0 = '9' - '0'
'9' = 9 + '0'
'8' ?? 8
'a'-'A'
'A'-'a'
'0'
? 'm' - 'a' + 'A' = 'M'
? 'M' - 'A' + 'a' = 'm'
? '8' - '0' = 8
? 8 + '0' = '8'
2.4.4 转义字符
?反斜杠后跟一个字符或数字
?字符常量, 代表一个字符 '\n' '\101' '\x41' 'A'
?所有字符都可以用转义字符表示
2.5 表达式
2.5.1 算术表达式
? 算术运算符
– 单目 + - ++ --
– 双目 + - * / %
注意 !
? % 模 (求余 ) 整型数据
5% 6= 5,9% 4= 1,100% 4= 0
? / 整数除整数, 得整数
1/2= 0,9/4= 2
?双目运算符两侧操作数的类型要相同
算术运算符的优先级和结合性
单目 + - ++ --
双目 * / %
双目 + -


从右向左
-5+3%2 = (-5)+(3%2) = -4
3*5%3 = (3*5)%3 = 0
-i++ -(i++)
算术表达式
例 2-15 数学式 --> C表达式
s(s-a)(s-b)(s-c)
(x+2)e2x
s*(s-a)*(s-b)*(s-c)
(x+2)*exp(2*x)
2.5.2 赋值 表达式
? 赋值运算符 =
? 赋值表达式
变量 = 表达式
?计算赋值运算符右侧 表达式 的值
?将赋值运算符右侧 表达式 的值赋给左侧的 变量
?将赋值运算符左侧的 变量 的值作为表达式的值
n = 2;
n = n+1;
? 赋值运算符的优先级和结合性
优先级较低, 从右向左
x=y=3; x=(y=3)
例 大小写字母转换
输入一个小写字母,输出对应的大写字母。
# include <stdio.h>
void main( )
{
char ch ;
scanf("%c",&ch);
ch = ch - 'a' + 'A';
printf("%c\n",ch);
}
2.5.3 逗号 表达式
? 表达式 1,表达式 2,……, 表达式 n
先计算表达式1, 然后计算表达式2,……, 最后
计算表达式 n的值, 并将表达式 n的值作为逗号
表达式的值,
? 逗号运算符的优先级最低, 从左向右
a = (3+5,4*6 )
a = 3+5,4*6
a=24
a=8
自增运算符和自减运算符
? 自增运算符 ++ 和自减运算符 --
int n,n++ ++n n-- --n (只适合变量运算)
– 使变量的值增 1或减 1
++n n++ n=n+1
--n n-- n=n-1
– 取变量的值作为表达式的值
++n,n=n+1; 取 n值作为表达式 ++n的值
n++,取 n值作为表达式 n++的值; n=n+1
自增运算和自减运算
int i,k;
i=2;
k=++i;
i=2;
k=i++;
i=3
i=3
k=3
k=2
k=i
i=i+1
i=i+1
k=i
例 2-17
#include <stdio.h>
void main( )
{
int a,b,c;
b=5; c=5;
a=++b+c--;
printf("%d,%d,%d\n",a,b,c);
a=b---c;
printf("%d,%d,%d\n",a,b,c);
a=-b+++c;
printf("%d,%d,%d\n",a,b,c);
}
b=b+1,a=b+c,c=c-1
a=b-c,b=b-1
a=-(b++)+c
a=(b--)-c
a=-b+c,b=b+1
复合算术赋值运算符
? 赋值运算符
– 简单赋值运算符 =
– 复合 ( 算术 ) 赋值运算符 += -= *= /= %=
? 赋值表达式
变量 赋值运算符 表达式
x += exp x = x + (exp)
例 2-18
#include <stdio.h>
void main( )
{
int x,y,z;
z=(x=7)+(y=3);
printf("%d,%d,%d\n",x,y,z);
x=y=z=x+2;
printf("%d,%d,%d\n",x,y,z);
x*=y-3;
printf("%d,%d,%d\n",x,y,z);
}
x=7,y=3,z=x+y
z=x+2,y=z,x=z
x=x*(y-3)
2.6 数据的存储和类型转换
2.6.1 数据的存储
? 整型数据的存储
设整数占 2个字节
1 000 0001 1000 0001
0 000 0001 1000 0001
符号位
1:负数
0:正数
原码 反码 补码
– 正数的原码、反码和补码相同
1的补码 0 000 0000 0000 0001
……
32767的补码 0 111 1111 1111 1111
(215-1)
– 负数 -1
? 原码 1 000 0000 0000 0001
? 反码 1 111 1111 1111 1110 原码取反
? 补码 1 111 1111 1111 1111 反码+ 1
原码 反码 补码
32767
– 补码 0 111 1111 1111 1111
-32767
– 原码 1 111 1111 1111 1111
– 反码 1 000 0000 0000 0000 原码取反
– 补码 1 000 0000 0000 0001 反码+ 1
-32768 = -32767-1
– 补码 1 000 0000 0000 0000
-32768 -1 0 1 32767
32767 0111 1111 1111 1111
……
1 0000 0000 0000 0001
0 0000 0000 0000 0000
-1 1111 1111 1111 1111
-2 1111 1111 1111 1110
……
-32767 1000 0000 0000 0001
-32768 1000 0000 0000 0000
32768 = 32767+1
1000 0000 0000 0000 = -32768
-32769 = -32768-1
0111 1111 1111 1111 = 32767
实型和字符型数据的存储
? 实型数据的存储
-1.2345e+02
符号位 阶码 尾数
? 字符型数据的存储
一个字节存储 ASCII码
2.6.2 整数类型的扩展
有符号 无符号 数据长度
int unsigned [int] 16或 32
short [int] unsigned short [int] 16
long [int] unsigned long [int] 32
无符号 unsigned
设整数占 2个字节
0000 0000 0000 0000 0
1111 1111 1111 1111 65535(216-1)
整数类型的最小取值范围
int -32768~32767 (-215~215-1)
short [int]
long [int] -2147483648~ 2147483647 (-231~231-1)
unsigned [int] 0~65535 (0~ 216-1)
unsigned short [int]
unsigned long [int] 0~4294967295 (0~ 232-1)
整型常量的表示
? 不能超出整型数据的取值范围
? 比长整型数还要大的数只能用实数来表示
? 整型常量的类型
– 整数后的字母后缀
?123L long
?123U unsigned
?123LU unsigned long
– 数值
整型数据的输入输出
printf(格式控制,输出参数 1,...,输出参数 n);
scanf(格式控制,输入参数 1,...,输入参数 n);
格式控制说明 %…
十进制 八进制 十六进制
int %d %o %x
long %ld %lo %lx
unsigned %u %o %x
unsigned long %lu %lo %lx
例 2-19
#include <stdio.h>
void main( )
{
int ai; long cl;
unsigned bu; unsigned long dul;
ai = 32767; bu = 65535U;
cl = -2147483648L; dul = 4294967295LU;
printf("%d,%u,%ld,%lu\n",ai,bu,cl,dul);
printf("%x,%x,%lx,%lx\n",ai,bu,cl,dul);
}
7fff,ffff,80000000,ffffffff
2.6.3 数据类型转换
不同类型数据的混合运算
– 类型转换
? 自动转换
? 强制转换
– 运算
自动类型转换 (非赋值运算 )
? 水平方向:自动
? 垂直方向:低 ?高
高 double ? float
unsigned long ? long
unsigned ? unsigned short
低 int ? char,short
自动类型转换 (非赋值运算 )
'A' + 12 – 10.05
65
77
66.95
高 double ? float
unsigned long ? long
unsigned ? unsigned short
低 int ? char,short
自动类型转换 (赋值运算 )
变量 赋值运算符 表达式
? 计算赋值运算符右侧 表达式 的值
? 将赋值运算符右侧 表达式 的值赋给左侧的 变量
? 将赋值运算符左侧的 变量 的值作为表达式的值
将赋值运算符右侧表达式的类型
自动转换成
赋值号左侧变量的类型
自动类型转换 (赋值运算 )
double x;
x = 1; x =?
short a = 1000;
char b = 'A';
long c = 80000;
c = a + b; c =?
int ai;
ai = 2.56; ai =?
int bi;
bi = 0x12345678L
bi =?
例 2-20
# include <stdio.h>
void main( )
{
long a,b,c;
a=1000000L;
b=1000*1000LU;
c=1000*1000;
printf("%ld,%ld,%ld\n",a,b,c);
}
运行结果为:
1000000,1000000,16960
强制类型转换
强制类型转换运算符
(类型名 ) 表达式
优先级同 ++,从右向左
(double)3
(int)3.8
(double)(5/2)
(double)5/2
3.0
3
2.0
2.5
运算符优先级
? ( )
? - + ++ -- (类型名)
? * / %
? + -
? = += -= *= /= %=
?,