数据类型
C语言中的数据类型可分为:基本类型、枚举类型、空类型及派生类型,其中基本类型又可分为整型、字符型、实型,派生类型又可分为数组类型、结构体类型、共用体类型、指针类型及函数类型,如图所示。
常量
C语言中常量包括符号常量(PI)、整型常量(-3)、实型常量(3.14)、字符型常量(‘a’)、字符串常量(“abc”)等。常量在程序执行中,值不发生改变,常量可以不经定义直接使用。
符号常量
1. 标识符
用来标识变量名、符号常量名、函数名、数组名、类型名、文件名的有效字符序列称为标识符。
能做为标识符的有效字符有三种:1. 26个英文字母 2. 数字0~9 3. 下划线
且第一个字符必须为字母或下划线。
例:max,sum,_sub,member_id,book_1 等
2. 符号常量
可以用一个标识符来表示一个常量,称之为符号常量(习惯上用大写字母表示)。
符号常量在使用前必须先定义,一般形式为:#define 标识符 常量
功能是把该标识符定义为其后的常量,在程序所有出现该标识符的地方,均以该常量代替运算。
例:求半径为r的圆面积及半径为r的球体积。
#include "stdio.h"
#define PI 3.1415 //若程序想要修改PI的值,只需在定义声明处修改即可
int main()
//本程序将实现求半径为r的圆面积和体积
{
float r, s, v; //分别声明实型变量,替代半径、面积和体积
r = 2.5;
s = r*r*PI; //面积公式
v = (4.0/3)*PI*r*r*r; //体积公式,注意体积V为实型变量
printf("s = %f\n",s);
printf("v = %f\n",v);
return 0;
}
3. 整型常量
十进制形式 首位不能为0,例:-2, 12,-222 等
八进制形式 必须以数字0开头,例:0114表示八进制数114,转换十进制为76
十六进制形式 必须以数字0和字母x开头,例:0x114为十六进制114,转换十进制是276
4. 编码规律
数据在内存中是以二进制编码来存放的,整形常量属于数值型数据,数值型数据在内存中是以补码形式来存储的。
正数的补码和原码相同
负数的补码是将该负数绝对值的二进制形式按位取反再加1。
例:求整型常量-18的补码(步骤如下):
整型常量18的原码:00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 10
整型常量18的补码仍与原码相同。
对18的原码各位取反:11 11 11 11 11 11 11 11 11 11 11 11 11 10 11 01
再加1,得-18的补码:11 11 11 11 11 11 11 11 11 11 11 11 11 10 11 10
左面第一位表示正负号,“0”表示“+”号,“1”表示“-”号。
实型常量
1. 十进制小数形式
十进制小数形式由数的符号、小数点和数字三部分组成。
必须含有小数点,例:2.38、0.57、-3.88、16. 、.66 等都是正确的表示形式。
2. 指数形式
指数形式由尾数、字母E/e、指数,三部分组成,例:26.8e-5
字母E(e)前必须有数字,字母E(e)后数字必须为整数。
例:2e6、2.8e-5、-23e-6、-.5e-3 均为合法的指数形式。
数学的指数表示形式:+(-)尾数 x 10^[+(-)n]
C语言指数表示形式:+(-)尾数 E(e) +(-)指数(n)
规范化指数形式:字母E或e前面小数部分,小数点左边有且只有一位非零数字(科学计数法)。
字符常量
用单引号括起来的一个字符称为字符常量。例:'a'、'A'、'='、'*'、'!' 等,都是合法的。
字符常量只能是一个字符,不能是多个字符。只能用单引号括起来,而不能是双引号或其他符号。
字符常量的方式仅适合于ASCII码表中的可印刷字符,而那些不可印刷的字符,如回车符、换行符等,是无法通过键盘输入至单引号内。为此引入一种特殊意义的字符常量——转义字符。
转义字符以反斜线“\”开头,后跟字母。常用的转义字符及作用如下所示:
表中的ddd和hh分别表示八进制和十六进制的 ASCII 代码。
如\101表示字符 ‘A’,\x41也表示字符 ‘A’,\0 或 \000表示 ASCII 代码为0的控制字符及空操作符。
例:
#include "stdio.h"
int main()
{
printf(" ab c\tde\t\"\\f\tg\n"); //"\t"跳到下一个制表位(占8列)
printf("book\tR\bS\n"); //先输出大写R,遇到“\b”回退一列,S覆盖R
return 0;
}
字符串常量
字符串常量由双引号括起来,例:"student"、"C"、"CHINA"、"$12.5" 等。
在内存中,字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串的字符个数+1,增加的一个字节存放一个字符 '\0',仅作为字符串的结束标志。
例:字符常量 'M' 在内存中占一个字节,字符串常量 "M" 在内存中占两个字节。
变量
在程序执行过程中,值可以改变的量成为变量。在使用变量前,必须先定义变量的数据类型。
变量名必须满足标识符的命名规则,遵循见名知意原则,严格区分大小写。
整型变量
整型变量的基本类型符为 int,短整型用 short 或 short int 定义,长整型用 long 或 long int 定义。
为了充分利用有限的存储空间,可以将变量定义为“无符号”类型,也就是将原本字节中表示正负号的第一位也用来存储数值。在整型变量前加上修饰符 unsigned 就是无符号类型,默认为有符号。
整型变量的字节数和取值范围: [注:2^n --> 2的n次方,2^n-1 --> 2的n次方 减一]
一个int型变量用4个字节来存储,所表示的范围为 -2147483648 ~ 2147483647,若超出范围则结果显示溢出。
#include "stdio.h"
int main()
//该程序将演示整型数据溢出的操作
{
int x, y;
x = 2147483647;
y = x + 1;
printf("x = %d, y = %d\n", x, y);
return 0;
}
//输出显示结果为:x = 2147483647, y = -2147483648
//当 x+1 后,超出了基本整形数据的范围,则数据溢出
实型变量
实型变量包括单精度(float型)和双精度(double型)两类。
整型变量的字节数和取值范围: [注:10^-38 --> 10的-38次方,10^-308 --> 10的-308次方]
一般情况下,单精度(float型)变量能接受的有效数字是 7 位,双精度(double型)是16位。
倘若数据的值超出取值范围,则超出的部分丢失,从而产生误差。
#include "stdio.h"
int main()
//本程序将体现实型数据的精度
{
float x;
double y;
x = 123456789.123; //float型只接受7位有效数字,超出部分将丢失
y = 123456789123456729.123; //double型只接受16位有效数字
printf("x = %f, y = %f\n", x, y);
return 0;
}
//运行结果为:x = 123456792.000000 前7位是精确的,后2位是随机值,小数点后面数字部分丢失
y = 123456789123456740.000000 只有前16位是精确的,后面部分都是不准确的
字符型变量
用字符型变量来存放一个字符型常量,计算机系统中存储的不是这个字符本身,而是ASCII码。
在C语言中,允许字符数据和整型数据通用,字符 'b' 既可用作 'b',也可作为十进制整数98、八进制整数142、十六进制整数62来使用,也可以参与整数的运算,反之亦然。
#include "stdio.h"
int main()
//该代码实现展示字符数据和整型数据的通用性
{
char x;
int y;
x = 98;
y = 'd';
printf("%c, %c\n", x, y);
printf("%d, %d\n", x, y);
return 0;
}
/*
运行结果为:
b, d
98, 100
*/
/*
因为字符数据和整型数据的通用性,
输出的x和y究竟是字符还是整数,
取决于引号内的控制字符(%c 或 %d)
*/
在ASCII码表中,大小写字母间相差32,可以用此关系实现大小写转换。
#include "stdio.h"
int main()
//此代码实现大小写字母的转换
{
char c1, c2;
c1 = 'A';
c2 = 'B';
printf("%c, %c\n", c1, c2);
c1 = c1 + 32;
c2 = c2 + 32;
printf("%c, %c\n", c1, c2);
return 0;
}
/*
运行结果为:
A, B
a, b
*/
算术运算
基本运算符“ + - * / ” 即加减乘除不再论述。
两个整数相除的结果取商的整数部分,把小数部分舍去。例:5/3=1,-9/4=-2
“ % ” ——求余运算符 或 模运算符。例: 5%3=2
求余运算要求参与运算的对象为整型或字符型数据,运算结果的正负与被除数相同。 例:9%2=1,-9%2=-1
优先级:算数运算符的优先级是先乘除和求余,后加减。
结合性:算术运算符的结合性为自左向右,即左结合性。若运算对象两侧是同一级运算符,则先进行左侧的运算。
自增、自减运算符
自增(++)运算符是让变量的值增1,自减(--)运算符是让变量的值减1。
当此类运算符放置位置不同,所产生的功能也不同。 ++ i , -- i 表示先对变量 i 加 1 或减 1,在参与其他运算。 i ++ , i -- 表示 i 先参与其他运算,再对变量 i 加 1 或减 1。
自增、自减运算符的结合方向为自右至左,即右结合性。例:- i -- 等价于 - ( i --)
#include "stdio.h"
int main()
//该代码展示自增运算符位置带来的影响
{
int i;
i = 5;
printf("%d\n", i++); //输出结果为5
return 0;
}
/*
若把上条语句改为:
printf("%d\n", ++i);
则输出结果为6.
*/
#include "stdio.h"
int main()
//自增运算符的应用实例
{
int i, j, k;
i = 3;
j = i++;
k = ++i;
printf("i = %d, j = %d, k = %d\n", i, j, k);
return 0;
}
/*
运行结果为:
i = 5, j = 3, k = 5
*/
复合赋值运算符:x += y 等价于 x = x+y x *= y-6 等价于 x = x * (y-6)
#include "stdio.h"
int main()
{
int x = 12;
x += x -= x * x;
printf("x = %d\n",x);
return 0;
}
//
运行结果为:x = -264
逗号表达式
一般表现形式为 表达式1, 表达式2
求值过程:先求出表达式1的值,再求出表达式2的值,逗号表达式的值为表达式2的值。
#include "stdio.h"
int main()
//该程序为逗号表达式的应用实例
{
int m, n, k, x, y;
m = 3;
n = 2;
k = 6;
x = ((y = m - n), (m * k));
printf("y = %d, x = %d\n", y, x);
return 0;
}
/*
程序运行结果:
y = 1, x = 18
*/
数据类型转换
C语言中,允许不同类型数据之间进行运算,但在运算前,须将数据转换为同一种类型的数据。
自动转换
数据类型自动转换由编译系统自动完成。
1. 转换按数据长度增加的方向自动进行,以保证精度不降低。
方向为:int -> unsigned -> long -> double
2. 实型数据的运算都是以双精度进行的,float单精度参与运算时,必须先转换成double型。
3. char型和short型参与运算时,必须先转换成int型,在进行运算。
竖直方向是必定的转换,水平方向表示自动转换方向。
在赋值运算时,当两边的数据类型不同时,均以运算符左边的变量类型为准,若右边的数据类型长度比左边长,则会丢失一部分精度,从而降低精度。
强制转换
当数据类型不符合实际需要时,可以进行强制类型转换。一般形式为:(类型说明符)(表达式)
强制类型转换后得到一个表达式的值,但并不改变原变量的类型。
#include "stdio.h"
int main()
//该代码体现数据类型的强制转换
{
int x, y = 3;
float z = 17.8;
x = (int)(z + 3.4) % y;
printf("x = %d\n", x); //输出结果为:x = 0
return 0;
}
章节代码
例2-1:
#include "stdio.h"
int main()
//此代码将展示自减运算
{
int x = 023; //“023”为八进制数,转化为十进制为19
printf("%d\n",--x); //自减运算,将19减1后采用%d取整数为18
return 0;
}
//运行结果为:18
例2-2:
#include "stdio.h"
int main()
//此代码将实现多重运算符的复合运算
{
double x1 = 2.5, y1 = 4.7;
int a1 = 7;
double b1;
b1 = x1 + a1 % 3 * (int)(x1 + y1) % 2 / 4;
printf("%f\n",b1);
}
//运行结果为:2.500000
例2-3:
#include "stdio.h"
int main()
//实现将大写英文字母A、B转换成小写字母a、b
{
char c1, c2;
printf("此程序可实现将大写英文字母转换为小写字母!\n");
printf("请输入两个大写字符:(两字符间使用空格隔开)\n");
scanf("%c %c", &c1, &c2);
c1 += 32;
c2 += 32;
printf("c1 = %c, c2 = %c\n", c1, c2);
return 0;
}
//此程序可实现将大写英文字母转换为小写字母!
请输入两个大写字符:(两字符间使用空格隔开)
A N
c1 = a, c2 = n
例2-4:
#include "stdio.h"
#define PI 3.14
int main()
{
//此程序将求半径r=3的圆面积
int r = 3;
float area;
area = r * r * PI;
printf("area = %f\n", area);
//求圆面积,用户输入半径大小
float r2;
printf("请输入圆的半径大小:\n");
scanf("%f", &r2);
area = r2 * r2 * PI;
printf("area = %f\n", area);
return 0;
} //在程序使用中,一般使用第二种方法
//可以让用户主动输入值,而不将目标值固定
//运行结果为:
area = 28.260000
请输入圆的半径大小:
3
area = 28.260000