C语言学习第十三天,今天终于学习到第二章了,类型运算符与表达式。
2.1 变量名
变量名是由字母和数字组成的序列,但其第一个字符必须为字母。下划线“_”被看作是字母,通常用于命名较长的变量名,可以提高其可读性。由于库例程的名字通常以下划线开头,因此变量名不要以下划线开头。大小写是有区别的,所以x与X是两个不同的名字。变量名一般使用小写字母,符号常量名全部使用大写字母。
对于内部名而言,至少前31各字符是有效的。对于外部名,ANSI标准仅保证前6各字符的唯一性,并且不区分大小写。类似于if、else、int、float等关键字是保留给语言本身使用的,不能把它们用做变量名。所有关键字重的字符都必须小写。
选择的变量名要能够尽量从字面上表达变量的用途,这样做不容易引起混淆。局部变量一般使用较短的变量名(尤其是循环控制变量),外部变量使用较长的名字。
2.2 数据类型及长度
char 字符型,占一个字节,可以存放本地字符集中的一个字符
int 整型,通常反映了所用机器中整数的最自然长度
float 单精度浮点型
double 双精度浮点型
此外,还可以在这些基本数据类型的前面加上一些限定符。short和long两个限定符用于限定整型
short int sh;
long int counter;
在上述这种类型声明中,关键字int可以省略。通常很多人也习惯这么做。
short类型通常为16为,long类型通常为32位,int类型可以为16位或32位。各编译器可以根据硬件特性自主选择合适的类型长度,但要遵循下列限制:short与int类型至少16位,而long类型至少32位,并且short类型不得长于int类型,int类型不得长于long类型。
类型限定符 signed与unsigned可用于限定 char类型或任何整型。unsigned类型的数总是正值或0,例如char如果是8位,那么unsigned char取值范围为0~255,signed char取值范围为-128~128.
long double类型表示高精度的浮点型。浮点型的长度也取决于具体的实现,float、double与long double类型可以表示相同的长度,也可以表示两种或三种不同的长度。
有关这些类型长度定义的符号常量以及其他与机器编译有关的属性可以在标准头文件
练习2-1 编写一个程序以确定分别有signed及unsigned限定的char、short、int与long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。后一种方法的实现较困难一些,因为要确定各种浮点类型的取值范围。
————————————————————————————————
#include
#include
#include
main() {
printf("signed char 取值范围: %d~%d\n", SCHAR_MIN, SCHAR_MAX);
printf("unsighed char 取值范围: %d~%d\n", 0, UCHAR_MAX);
printf("signed short 取值范围:%d~%d\n", SHRT_MIN, SHRT_MAX);
printf("unsigned short 取值范围:%d~%d\n", 0, USHRT_MAX);
printf("signed int 取值范围:%d~%d\n", INT_MIN, INT_MAX);
printf("unsigned int 取值范围:%ld~%ld\n", 0, UINT_MAX);
printf("signed long 取值范围:%ld~%ld\n", LONG_MIN, LONG_MAX);
printf("unsigned int 取值范围:%ld~%ld\n", 0, ULONG_MAX);
printf("double 取值范围: %g~%g\n", DBL_MIN, DBL_MAX);
}
————————————————————————————————
2.3 常量
类似于1234的整数常量属于int类型。long类型的常量以字母l或L结尾,如123456789L。如果一个整数太大以至于无法用int类型表示,也可以被当作long类型处理。无符号常量以字母u或U结尾。后缀ul或UL表明是unsigned long类型。
浮点数常量包含一个小数点(如123.4)或一个指数(如1e-2),也可以两者都有。没有后缀的浮点数常量为double类型。后缀f或F表示float类型,而后缀l或L表示long double类型。
整数除了用十进制表示以外,还可以用八进制或十六进制表示。带前缀0的整型常量表示它为八进制;带前缀0x或0X,则表示它为十六进制。例如,十进制31可以写成八进制037,也可以写成十六进制形式0x1f或0x1F。把进制或十六进制的常量也可以使用后缀L表示long类型,使用后缀U表示unsigned类型。类如0XFUL是一个unsigned long类型(无符号长整型)的常量,其值等于十进制数15。
一个字符常量是一个整数,书写时将一个字符括在单引号中,如'x'。字符在机器字符集中的数值就是字符常量的值。例如在ASCII字符集中,字符'0'的值为48,它与数值0没有关系。如果用字符'0'代替这个与具体字符集有关的值(比如48),那么,程序就无需关心该字符对应的具体值,增加了程序的易读性。字符常量一般用来与其他字符进行比较,但也可以像其他整数一样参与数值运算。
某些字符可以通过转义字符序列(例如,换行符\n)表示为字符或字符串 常量。转义字符序列看起来像两个字符,但只表示一个字符。另外,我们可以用
'\ooo'
表示任意得字节大小的位模式。其中,ooo代表1~3个八进制数字(0~7).这种位模式还可以用
'\xhh'
表示,其中hh是一个或多个十六进制数字(0~9,a~f, A~F)。因此,我们可以按照下面的形式书写语句:
#define VTAB '\013' /*ASCII 纵向制表符*/
#define BELL '\007', /* ASCII响铃符 */
上述语句也可以用十六进制的形式书写为:
#define VTAB ’\xb‘ /* ASCII纵向制表符 */
#define BELL '\x7' /* ASCII响铃符 */
ANSI C语言中的全部转义字符序列如下所示:
\a 响铃符 \\ 反斜杠
\b 回退符 \? 问号
\f 换页符 \' 单引号
\n 换行符 \" 双引号
\r 回车符 \ooo 八进制数
\t 横向制表符 \xhh 十六进制数
\v 纵向制表符
字符常量'\0'表示值为0的字符,也就是空字符(null)。我们通常用'\0'的形式代替0,以强调某些表达式的字符属性,但其数字值为0。
常量表达式是仅仅只包含常量的表达式。这种表达式在编译时求值,而不在运行时求值。它可以出现在常量可以出现的任何位置,例如:
#define MAXLINE 1000
char line[MAXLINE+1];
或
#define LEAP 1 /* 闰年 */
int day[31+28+LEAP=31+30+31+30+31+31+30+31+30+31];
字符串常量也叫字符串字面值,是用双引号括起来的0个或多个字符组成的字符序列。例如
"I am a string"
或
“” /* 空字符串 */
都是字符串。双引号不是字符串的一部分,它只用于限定字符串。编译时可以将多个字符串常量连接起来,例如,
"hello, " "world" 等价于 "hello, world"
字符串常量的连接为教长的字符串分散在若干各源文件行中提供了支持。
从技术角度看,字符串常量就是字符数组。字符串的内部表示使用一个空字符'\0'作为串的结尾,因此,存储字符串的物理存储单元比括在双引号中的字符数多一个。这种表示方法也说明,C语言对字符串的长度没有限制,但程序必须扫描完整个字符串后菜能确定字符串的长度。标准库函数strlen(s)可以返回字符串参数s的长度,但长度不包括末尾的'\0'.
下面是我们设计的strlen函数的一个版本:
/* strlen函数:返回s的长度 */
int strlen(char s[]) {
int i;
i = 0;
while(s[i] != '\0)
++i;
return i;
}
标准头文件
我们应该搞清楚字符常量与仅包含一个字符的字符串之间的区别:'x'与"x"是不同的。前者是一个整数,其值是字母x在机器字符集中对应的数值;后者是一个包含一个字符以及一个结束符'\0'的字符数组。
枚举常量是另外一种类型的常量。枚举是一个常量整型值的列表,例如:
enum boolean { NO, YES };
在没有显示说明的情况下,enum类型中第一个枚举名的值为0,第二个为1,依次类推。如果只指定了部分枚举名的值,那么未指定值的枚举名的值将依着最后一个指定值相后递增
enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t',
NEWLINE = '\n', VTAB = '\V', RETURN = '\R' };
/* FEB 的值为2, MAR的值为3, 依次类推 */
enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
不同枚举中的名字必须互不相同。同一枚举中不同名字可以具有相同的值。
枚举为建立常量值与名字之间的关联提供了一种便利的方式。相对于#define语句来说,它的优势在于常量值可以自动生成。