1.C语言数据类型
1.1 基本类型:其值不可以再分解为其他类型
1.1.1 整型:整型常量,整型变量。
整型常量:有3种形式:十进制(没有前缀,数码为0~9),八进制(以0为前缀,数码取值为0 ~ 7),十六进制(以0X或0x为前缀,数码取值为0 ~ 9和A - F(a ~ f))。注:整型常量可添加后缀,主要根据其类型来添加。
整型变量:变量是CPU为程序开辟的一块内存地址空间的代号,因此其实质存储形式是二进制(即数值是以01代码形式存储在这块内存空间中的,是以补码形式表示的)。一个字节Byte = 8bit即8位。补码:正数的补码即为其原码;负数的补码为其原码按位取反,再加1。(所以注意内存溢出的情况)
/#include <stdio.h>
void main()
{
int a, b, c;
a = 32767;
b = a + 1;
printf("%d, %d\n", a, b)
}
//输出 32767(0111111111111111), -32768(1000000000000000)
//这里内存溢出了,因为再补码中,最左边第一位表示的是符号位(0表示“+”, 1表 示“-”),当a=32767时即为在16位下所能表示的最大数值,如果再+ 1,则引发内存溢 出,造成0111111111111111 + 1 == 1000000000000000,即为-32768(因为在内存中数值的表示方式为补码,正数的补码即为本身,所以011111111111111 == 32767; 而 1000000000000000表示的是负数,其的反码为 1111111111111111 == (1)111111111111111,所以后15位再+1,即为1000000000000000 == 32768,再算上第一位符号位,即为-32768)
整型的分类:1)基本型:类型说明符为int,占2字节;
2)短整型:类型说明符为short int 或 short,占2字节
3)长整型:类型说明符为long int 或 long, 占4字节
4)无符号整形:类型说明符为unsigned
1.1.2 字符型:字符常量,字符变量,字符串常量。
字符常量定义:用单引号括起来的一个字符(不可以是字符串)。例如:’a’, ‘+’, ‘?’, ‘=’ 都是合法字符常量。
字符常量具有以下特点:1)字符常量只能用单引号括起来,不能用双引号或其他括号;2)字符常量只能是单个字符,不能是字符串;3)字符可以是字符集中的任意字符,但是数字被定义为字符常量后就不能参与数值运算。例,’5’和5是不同的,’5’是字符常量,不可以参与数值运算,但是5仍旧可以。
转义字符:转义字符是一种特殊的字符常量。以反斜杠”\”开头,后面跟一个或几个字符。转义字符具有特殊的意义, 不同于字符原本的意义。例如,”\n”表示回车。(注:这里是使用的双引号,所以它又有别于字符串常量。)目的:用来表示一般字符不便于表示的控制代码。
字符变量定义:字符变量用来存储字符常量,即单个字符。字符变量的类型说明符是char,在函数中定义字符变量即:char a, b;
字符型数据在内存中的存储形式及使用方法:每个字符型变量被分配一个字节的内存空间,因此只能存储一个字符型常量,且该字符型常量是以ASCII码的形式存放在该变量的存储空间中的。例,char a = ’A’; 则a所指代的内存空间中存储的是’A’的ASCII码65的二进制形式01000001。
/#include <stdio.h>
void main()
{
Char a, b;
a = 65;
b = 66;
printf(“%c, %c\n”, a, b)
printf(“%d, %d\n”, a, b)
}
//输出:A, B
65, 66
//在该例中,a与b是字符型变量,当赋值时赋予整型数据a = 65,b = 66,因此输出时取决于printf函数中要求输出的格式,如要求输出”%c”即字符型时,即按照65, 66的ASCII码输出相对应的字符型常量’A’, ‘B’;如果要求输出”%d”即整型时,即按照原先的赋值输出65,66(注:这里的65,66是整型)。
字符串常量定义:是有一对双引号括起来的字符序列(其长度可以为多个字符也可以是一个字符)。
字符常量与字符串常量的区别:1)字符常量用单引号,字符串常量用双引号;2)字符常量只能是单个字符,字符串常量可以包含一个或多个字符;3)字符常量只占1个字节,而字符串常量占自身字节长度+1,增加的一个字节是为了存放转义字符”\O”(字符串结束的标志);4)可以把一个字符常量赋值给字符变量,但是不能把一个字符串常量赋值给字符变量(因为,字符变量仅有1字节的内存空间,而字符串常量往往至少占2个字节,因此会造成内存溢出)。
1.1.3 浮点型:浮点型常量,浮点型变量。(注:在浮点数计算中需要注意舍入误差,因此在不同精度数字计算时需要先将低精度转化为高精度(计算机内部执行),再进行计算)。
浮点型常量只采用十进制。有两种形式:十进制小数形式:由数码0~9和小数点组成;指数形式:由十进制数,加阶码标志“E”或“e”及阶码(阶码必须为十进制整数)组成(合法指数形式为3.11E5 == 3.11 * 10^5 == 311000)。注:浮点型常量可添加后缀,主要根据其类型来添加。
浮点型变量:
浮点型变量分类:1)单精度(float)一般编译器中占4个字节(32位)内存空间(注:根据不同编译器,所占内存字节数可能会有变化),数值范围为3.4E-38 ~ 3.4E38,只能提供7位有效数字;2)双精度(double)占8个字节(64位)内存空间,其数值范围为(1.7E-308 ~ 1.7E308)提供16为有效数字;3)长双精度(long double)
1.2 指针类型:指针是一种特殊的,同时又是具有重要作用的数据类型。 其值用来表示某个变量在内存储器中的地址。虽然指针变量的取值类似于整型量,但是这两个类型是完全不同的量。
1.3 构造类型:构造类型是根据已经定义的一个或多个数据类型用构造的方法来定义的。就是说, 一个构造类型的值可以分解为若干个“成员” 或 “元素”。而每个“成员”都是一个基本类型或者又是一个构造类型。
1.4 空类型:在调用函数值时, 通常应向调用者返回一个函数值。这个返回的函数值时具有一定的数据类型的,应在函数定义及函数说明中给以说明。但是也有一类函数,调用后并不需要向调用者返回函数值, 这种函数可以定义为“空类型”。其类型说明符为void。
1.5 常量与变量:
常量定义:在程序执行过程中,其值不发生改变的量成为常量。
符号常量:用标识符代表一个常量。在使用前必须先定义:#define 标识符 常量
/#define PRICE 30
void main()
{
int num, total;
num = 10;
total = num * PRICE;
printf("total = %d", total);
}
这里的#define 时一条预处理命令,称为宏定义命令,其功能时把该标识符定义为其后的常量值。一经定义,以后在程序中所有出现该标识符的地方均以该常量值代替(#define后面的常量值一改则全改)。注:习惯上符号常量的标识符用大写字母,变量标识符用小写字母。
变量定义:其值可以改变的量成为变量。
这里的“k” 即为变量。注:变量定义必须放在变量使用之前,且一般放在函数体的开头部分。
1.6 各类数值型数据之间的混合运算:
在不同数值类型数据进行混合运算时,需要先把它们的数值类型转换为同一类型,才能进行下一步运算。有两种转换方式:(1)自动转换;(2)强制转换
(1)自动转换:1)若参与运算的数据的类型不同,先转换为同一类型,再运算(在自动转换的情况下,如(1)char a = 'A'; int b =2; printf("%c", a + b); 输出:C。 (2)char a = 'A'; int b =2; printf("%d", a + b); 输出:67。 (3)float a = 2.33; int b =2; printf("%f", a + b); (a,b转换为double类型再相加)输出:4.330000。 (4)float a = 2.33; int b =2; printf("%d", a + b);(编译时会warning,输出错误数字,因为在编译时计算机将a,b自动转换为double类型,然后相加,当要求输出int类型时需要强制转换,否则出错。 (5)long a = 23; int b =2; printf("%d", a + b);(编译时会warning,输出正确数字25, 因为在编译时计算机将a,b自动转换为long int类型,然后相加得到long int类型的25,因此输出int类型仍为25) );2)按照数据长度增加的方向进行转换,以保证精度不降低。例,int和long数据相加时,先把int数据转换成long再进行运算;3)所有的浮点运算都是以双精度进行的,即使所有的元素都是float类型,也都要先转换成double再进行运算(保证数值的最低舍入误差)。4)char和short参与运算时必须先转换为int(注:char型根据其ASCII码进行转换,如果char a = ‘5’,要以5进行运算的话需可以进行自动转换(因为字符’5’对应的ASCII码表中的数值也是5)也可以进行强制转换(直接 a =int(a),得出数字5));5)在赋值运算中,赋值号两边的数据类型不同时,赋值号右边的值的类型转换为赋值号右边的变量的类型。当赋值号右边的数据类型的长度长于左边时,将会按照四舍五入的方式来降低部分精度(即丢失部分数据)。(例:char a = 65; 这里的a是char型,而65是int型,因此要将65转换为其所对应的ASCII码01000001,再转换成对应的字符型'A'然后赋给a)。
//例
/#include <stdio.h>
void main()
{
float PI = 3.14159;
int s, r = 5;
s = r * r * PI;
Printf(“s = %d\n”, s)
}
\输出:s = 79
\计算时,首先PI和r都转换为double,然后相乘,得到的double型数值四舍五入成int型赋给s。
(2)强制转换:转换形式:(类型说明符)(表达式)。 其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。
例,(float) a 将a强制转换成float类型
(int) (x + y) 将x, y强制转换成int(注,这里的x和y都要用括号括起来,因为x,y都要强制转换)
使用强制转换的注意事项:
1)类型说明符和表达式都得加括号(表达式为单个变量可以不加),例如把(int) (x+y)写成(int) (x) + y则变成先把x强制转换成int再与y相加。
2)无论是强制转换还是自动转换,都是临时性的,都不会改变数据说明时对该变量定义的类型(例,int a = 3, b =5; float c; c = (float) (a + b); 然而a和b仍旧是int类型)。
1.7 算术运算符和算术表达式
算数运算符:算数运算符分1)单目运算符;2)双目运算符;3)三目运算符
运算符优先级:
运算符结合性:1)左结合性(自左向右)(如”-”,”+”);2)右结合性(自右向左)(如赋值运算符”=”, x = y = z,即x = (y = z))。
赋值运算的类型转换注意事项:当赋值运算符左右两边类型不同时,系统自动进行类型转换,将右边的类型转换为左边的类型:1)浮点型赋予整型,舍去小数部分; 2)整型赋予浮点型,数值不变,但以浮点型式存放(小数部分的值为0);3)字符型赋予整型,因为字符型为1个字节,而整型为2个字节,因此将字符的ASCII码值放在整型变量的低八位,高八位全为0。整型赋给字符型,只把低八位赋给字符变量(因此一个字符变量存放的int值范围为-128~256,这里需要注意的是最左边第一位为符号位,当输入负值时,其它位求反再加1得补码(其实经过实际测试,当输入为正数时,但是输入值超过127时,printf("%d", a)输出的是一个负值,因为127 == 01111111,而128 == 100000000(编译器自动认为是负数),即(1)0000000求反(1)1111111,再+1得(1)10000000 == - 128))。
再赋值运算符”=”之前加上其他二目运算符可以构成复合运算符,如 +=, -=, *=, /=, %=, <<=, >>=, &=, ^=, !=等。
逗号运算符 “,”, 功能是把两个表达式连接起来组成一个表达式。
一般形式是:表达式1, 表达式2;
其求值过程是,分别求出2个表达式的值,然后以表达式2的值作为整个逗号表达式的值(扩展到表达式n,则表达式n的值即为整个逗号表达式的值)。
//例
/#include <stdio.h>
void main()
{
int a = 2, b = 3, c = 4, x, y;
y = (x = a + b), b + c;
printf(“y = %d, x = %d”, y, x);
}
//输出:y = 7, x = 5