C语言入门系列之2.数据类型、运算符和表达式
数据类型,运算符和表达式
- 一、数据类型
- 1.数据类型
- 2.常量和变量
- 常量和符号变量
- 变量
- 3.整型数据
- 整型常量的表示方法
- 整型变量
- 4.实型数据
- Ⅰ.实型常量的表示方法
- Ⅱ.实型变量
- 实型数据在内存中的存放形式
- 实型变量的分类
- 实型数据的舍入误差
- 5.字符型数据
- 字符常量
- 字符变量
- 转义字符
- 字符串常量
- 6.变量赋初值
- 7.变量类型转换
- 自动类型转换
- 强制类型转换
- 二、运算符和表达式
- 1.基本算术运算符
- 2.运算符的优先级和结合性
- 3.高级运算符
- 强制类型转换运算符
- 自增、自减运算符
- 赋值运算符和赋值表达式
- 逗号运算符和逗号表达式
一、数据类型
C语言常见数据类型如下:
1.数据类型
- 基本数据类型 基本数据类型最主要的特点是,其值不可以再分解为其他类型。 也可以说,基本数据类型是自我说明的。
- 构造数据类型
构造数据类型是根据已定义的一个或多个数据类型用构造的方法来定义的。
也就是说,一个构造类型的值可以分解成若干个“成员”或“元素”。每个“成员”都是一个基本数据类型或一个构造类型。
在C语言中,构造类型有以下几种:
- 数组
- 结构体
- 共用体(联合)类型
- 指针类型 指针是一种特殊的、且具有重要作用的数据类型,其值用来表示某个变量在内存储器中的地址。 虽然指针变量的取值类似于整型量,但这是两个类型完全不同的量,因此不能混为一谈。
- 空类型
在调用函数值时,通常应向调用者返回一个函数值,这个返回的函数值是具有一定的数据类型的,应在函数定义及函数说明中给以说明。
例如在上一节例题中给出的max函数定义中,函数头为
int max(int a, int b);
,其中int类型说明符即表示该函数的返回值为整型量。 但是,也有一类函数,调用后并不需要向调用者返回函数值,这种函数可以定义为“空类型” ,其类型说明符为void。
2.常量和变量
对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。 在程序执行过程中,其值不发生改变的量称为常量,其值可变的量称为变量。 它们可与数据类型结合起来分类,例如,可分为整型常量、整型变量、浮点常量、浮点变量、字符常量、字符变量、枚举常量、枚举变量。 在程序中,常量是可以不经说明而直接引用的,而变量则必项先定义后使用。 整型量包括整型常量、整型变量。
常量和符号变量
在程序执行过程中,其值不发生改变的量称为常量。 符号常量:用标示符代表一个常量。 在C语言中,可以用一个标识符来表示一个常量,称之为符号常量。 符号常量在使用之前必须先定义,其一般形式为:
#define 标识符 常量
其中#define
也是一条预处理命令(预处理命令都以#开头),称为宏定义命令,其功能是把该标识符定义为其后的常量值。一经定义,以后在程序中所有出现该标识符的地方均代之以该常量值。
习惯上符号常量的标识符用大写字母,变量标识符用小写字母,以示区别。 举例如下:
#include <stdio.h>
#define PRICE 30
void main()
{
int num, total;
num = 10;
total = num * PRICE;
printf("total=%d", total);
}
打印:
total=300
其中:
#define PRICE 30
用标识符代表一个变量,称为符号变量;
符号常量与变量不同,它的值在其作用域内不能改变,也不能再被赋值。
使用符号常量的好处:
- 含义清楚;
- 能做到”一改全改“。
变量
其值可以改变的量称为变量。一个变量应该有一个名字,在内存中占据一定的存储单元。 变量定义必项放在变量使用之前,一般放在函数体的开头部分。 如下:
int k = 3;
要区分变量名和变量值是两个不同的概念,在上例中,k是变量名,3是变量值。
3.整型数据
整型常量的表示方法
整型常量就是整常数。 在C语言中,使用的整常数有八进制、十六进制和十进制三种:
- 十进制整常数 十进制整常数没有前缀,其数码为0-9。 以下各数是合法的十进制整常数: 237、-568、65535、1627等。
- 八进制整常数 八进制整常数必须以0开头,即以0作为八进制数的前缀,数码取值为0-7。 八进制数通常是无符号数。 以下各数是合法的八进制数: 015(十进制为13)、0101(十进制为65)、0177777(十进制为65535)。
- 十六进制整常数 十六进制整常数的前缀为0X或0x,其数码取值为0-9、A-F或a-f。 以下各数是合法的十六进制整常数: 0X2A(十进制为42)、0XA0 (十进制为160)、0xFFFF (十进制为65535)。
在程序中是根据前缀来区分各种进制数的,在书写常数时不要把前缀弄错造成结果不正确。
整型常数的后缀: 在16位字长的机器上,基本整型的长度也为16位,因此表示的数的范围也是有限定的。十进制无符号整常数的范围为0-65535,有符号数为-32768 - +32767,八进制无符号数的表示范围为0 - 0177777,十六进制无符号数的表示范围为0X0 - 0XFFFF或0x0 - 0xFFFF。 如果使用的数超过了上述范围,就必须用长整型数来表示,长整型数是用后缀 L或l 来表示的。
整型变量
变量定义的一般形式为:
类型说明符 变量名标识符, 变量名标识符, ...;
例如:
int a,b,c; // a,b,c为整型变量
long x,y; // x,y为长整型变量
unsigned p,q; // p,q为无符号整型变量
在书写变量定义时,应注意以下几点:
- 允许在一个类型说明符后,定义多个相同类型的变量,各变量名之间用“,”号间隔,类型说明符与变量名之间至少用一个空格间隔。
- 最后一个变量名之后必须以“;”号结尾。
- 变量定义必须放在变量使用之前。 一般放在函数体的开头部分。
整型数据在内存中的存放形式是二进制,在上例中声明k变量,值为3,以二进制存储示意如下:
补充–内存中的二进制存储: 1字节Byte = 8位bit。 数值是以补码表示的:
- 正数的补码与原码相同;
- 负数的补码 将该数的绝对值的二进制形式按位取反再加1。 举例说明–求-10的补码: 10的原码: 00001010 取反: 11110101 再加1,得到-10的补码: 11110110 可以得到,最高位是符号位,1表示负数,0表示整数。
整型变量的分类:
- 基本型 类型说明符为int,在内存中占4个字节。
- 短整型 类型说明符为short int或short,在内存中占2个字节。
- 长整型 类型说明符为long int或long,在内存中占4个字节。
- 无符号型 类型说明符为unsigned。
注意: 这里占多少个字节跟具体的系统和编译器规定有关。
在本机查看不同类型所占位数测试:
#include <stdio.h>
void main()
{
printf("%dn", sizeof(int));
printf("%dn", sizeof(short));
printf("%dn", sizeof(long));
printf("%dn", sizeof(unsigned));
}
打印:
4
2
4
4
整型变量信息如下:
类型说明符 |
数的范围 |
字节数 |
---|---|---|
int |
-231 - (231-1) |
4 |
unsigned int |
0 - (232-1) |
4 |
short int |
-215 - (215-1) |
2 |
unsigned short int |
0 - (216-1) |
2 |
long int |
-231 - (231-1) |
4 |
unsigned long |
0 - (232-1) |
4 |
整型变量的定义和使用举例如下:
#include <stdio.h>
void main()
{
int a, b, c, d;
unsigned u;
a = 5;
b = -15;
u = 12;
c = a + u;
d = b + u;
printf("a+u=%d, b+u=%dn", c, d);
}
打印:
a+u=17, b+u=-3
在编译运行时a、b、c、d与u的数据类型不一样,会自动将无符号型转化为默认类型有符号型再进行计算。
整型数据的溢出举例如下:
#include <stdio.h>
void main()
{
short int a, b;
a = 32767;
b = a + 1;
printf("%d, %d", a, b);
}
打印:
32767, -32768
显然,出现了负数-32768。 解释:在本机编译环境中,short int是2个字节16位,216=65536,65536÷2=32768,即short int有符号型的范围是 -32768-32767,而程序中b的值为32768,超出范围即溢出,其二进制为1000000000000000,此时最高位为1表示负数,所以显示了-32768。
再举一个例子,如下:
#include <stdio.h>
void main()
{
long x, y;
int a, b, c, d;
x = 5;
y = 6;
a = 7;
b = 8;
c = x + a;
d = y + b;
printf("c=x+a=%d, d=y+b=%d", c, d);
}
打印:
c=x+a=12, d=y+b=14
从程序中可以看到: x、y是长整型变量,a、b是基本整型变量,它们之间允许进行运算,运算结果为长整型。但c,d被定义为基本整型,此最后结果为基本整型。 本例说明,不同类型的量可以参与运算并相互赋值,其中的类型转换是由编译系统自动完成的。
4.实型数据
Ⅰ.实型常量的表示方法
实型也称为浮点型,实型常量也称为实数或者浮点数。 在C语言中,实数只采用十进制。 它有二种形式:十进制小数形式和指数形式:
- 十进制小数形式 由数码0-9和小数点组成,必须有小数点。 例如0.0、25.0、5.789、0.13、5.0、300.、-267.8230等均为合法的实数。 标准C允许浮点数使用后缀,后缀为 f或F 即表示该数为浮点数,如 356f 和 356. 是等价的。
- 指数形式 由十进制数、阶码标志“e”或“E”和阶码(只能为整数,可以带符号)组成。 其一般形式为: aEn(a为十进制数,n为十进制整数) 例如: 2.1E5 (等于2.1105) 3.7E-2 (等于3.710-2) 0.5E7 (等于0.5107) -2.8E-2 (等于-2.810-2) 以下不是合法的实数: 345 (无小数点) E7 (阶码标志E之前无数字) -5 (无阶码标志) 53.-E3 (负号位置不对) 2.7E (无阶码)
Ⅱ.实型变量
实型数据在内存中的存放形式
实型数据一般占4个字节(32位)内存空间,按指数形式存储。 浮点数的二进制存储方式如下:
举例3.14159在内存中的存放形式如下:
符号 |
小数部分 |
指数部分 |
---|---|---|
+ |
.314159 |
1 |
- 小数部分占的位(bit)数愈多,数的有效数字愈多,精度愈高;
- 指数部分占的位数愈多,则能表示的数值范围愈大。
实型变量的分类
- 单精度(float型)
- 双精度(double型)
- 长双精度(long double型)
在Turbo C中单精度型占4个字节(32位)内存空间,其数值范围为3.4E-38-3.4E+38,只能提供七位有效数字;双精度型占8个字节(64位)内存空间,其数值范围为1.7E-308~1.7E+308,可提供16位有效数字。
类型说明符 |
比特数(字节数) |
有效数字 |
数值范围 |
---|---|---|---|
float |
32(4) |
6-7 |
-2128 - 2128 |
double |
64(8) |
15-16 |
-21024 - 21024 |
long double |
128(16) |
18-19 |
-216384 - 216384 |
实型数据的舍入误差
测试如下:
#include <stdio.h>
int main()
{
float a, b;
a = 123456.789e5;
b = a + 20;
printf("%fn", a);
printf("%fn", b);
return 0;
}
打印:
12345678848.000000
12345678848.000000
显然,a的值已经不准确,整数部分后3位产生误差,同时b在a的基础上加20(两位数,在后边的3位误差之内)也会产生误差。
计算以下表达式的值:
(1)1.0 / 3 * 3等于多少? (2)3 / 2呢? (3)1 / 3 * 3呢?
通过程序计算:
#include <stdio.h>
int main()
{
printf("%fn", 1.0 / 3 * 3);
printf("%fn", 3 / 2);
printf("%fn", 1 / 3 * 3);
return 0;
}
打印:
1.000000
0.000000
0.000000
5.字符型数据
字符型数据包括字符常量和字符变量。
字符常量
字符常量是用单引号括起来的一个字符。 例如:‘a’、‘b’、’=’、’+’、’?'等都是合法字符常量。
在C语言中,字符常量有以下特点:
- 字符常量只能用单引号括起来,不能用双引号或其它括号。
- 字符常量只能是单个字符,不能是字符串。
- 字符可以是字符集中任意字符,但数字被定义为字符型之后就不能参与数值运算。 如’5’和5是不同的,'5’是字符常量,不能参与运算。
字符变量
字符变量用来存储字符常量,即单个字符,类型说明符是char。 字符变量类型定义的格式和书写规则都与整型变量相同,例如:
char a, b;
转义字符
转义字符是一种特殊的字符常量,以反斜线""开头,后跟一个或几个字符。
转义字符具有特定的含义,不同于字符原有的意义,故称转义字符。
例如,在之前的练习中printf()
函数的格式串中用到的 n 就是一个转义字符,其意义是回车换行。
转义字符主要用来表示那些用一般字符不便于表示的控制代码。
所有的转义字符及其含义如下:
转义字符 |
含义 |
ASCII码值(十进制) |
---|---|---|
a |
响铃(BEL) |
007 |
b |
退格(BS) ,将当前位置移到前一列 |
008 |
f |
换页(FF),将当前位置移到下页开头 |
012 |
n |
换行(LF) ,将当前位置移到下一行开头 |
010 |
r |
回车(CR) ,将当前位置移到本行开头 |
013 |
t |
水平制表(HT) (跳到下一个TAB位置) |
009 |
v |
垂直制表(VT) |
011 |
代表一个反斜线字符’ |
092 |
|
’ |
代表一个单引号(撇号)字符 |
039 |
" |
代表一个双引号字符 |
034 |
? |
代表一个问号 |
063 |