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
运算符优先级
( )
- + ++ -- (类型名)
* / %
+ -
= += -= *= /= %=
,
高低