2.1 常量:数字常量、字符常量和字符串字面量
在程序运行过程中,其值不能被改变的量称为 常量。如例 3.1 程序中的 5,9,32 和例 3. 2 程序中的 1000,0. 0036,0.0225,0.0198 是常量。
2.1.1 数字常量
- 整型常量:即整常数。如 1000,12345,0,-345 等都是整型常量。在C语言中,整常数可用以下三种形式表示:
- 十进制整数。如:123,-456。
- 八进制整数。以 0 头的数是八进制数。如:0123 表示八进制数 123,等于十进制数 83,-011 表示八进制数 -11,即十进制数 -9。
- 十六进制整数。以 0x 开头的数是 16 进制数。如:0x123,代表 16 进制数 123,等于十进制数 291。 -0x12 等于十进制数 -10。
-
实型常量(浮点型常量)。有两种表示形式:
- 十进制小数形式,由数字和小数点组成。如: 123.456,0.345,-56. 79,0.0,12.0 等。
- 指数形式,如 12.34e3(代表 $12. 34*10^3$),-346.87e-25(代表 $-346. 87*10^{-25}$),0.145E25(代表 $0.145*10 ^{-25}$)等。由于在计算机输人或输出时,无法表示上角或下角,故规定以字母 e 或 E 代表以 10 为底的指数。但应注意:e 或 E 之前必须有数字,且 e 或 E 后面必须为整数。如不能写成 e4,12e2.5。
- 一个浮点型数据一般在内存中占 4 个字节(32 位)。与整型数据的存储方式不同,浮点型数据是按照指数形式存储的。系统把一个浮点型数据分成小数部分和指数部分,分别存放。指数部分采用规范化的指数形式。
- C 编译系统将浮点型常量作为双精度来处理。例如:$f = 2.45678 * 4523.65$。系统先把 2.45678 和 4523.65 作为双精度数,然后进行相乘的运算,得到的乘也是一个双精度数。最后取其前 7位赋给浮点型变量 f。如是在数的后面加字母 f 或 F(如1.65f,654.87F),这样编译系统就会把它们按单精度(32 位)处理。
注意:
- 一个整数,如果其值在 -32768~+32767 范围内,认为它是 int 型,它可以赋值给 int 型和 long int 型变量。
- 一个整数,如果其值超过了上述范围,而在 -2147483637~+2147483647 范围内,则认为它是为长整型。可以将它赋值给一个 long int 型变量。
- 一个整常量后面加一个字母 u 或 U,认为是 unsigned int 型,如 12345u,在内存中按 unsigned int 规定的方式存放(存储单元中最高位不作为符号位,而用来存储数据)。如果写成 -12345u,则先将 -12345 转换成其补码 53191,然后按无符号数存储。
- 在一个整常量后面加一个字母 l 或 L,则认为是 long int 型常量。例如:123l,432L,0L 用于函数调用中。
- 如果函数的形参为 long int 型,则要求实参也为 long int 型。
2.1.2 字符常量
- 普通字符,用单撇号括起来的一个字符,如:
'a'
,'Z'
,'3'
,'?'
,'#'
。不能写成'ab'
或'12'
。请注意:单撇号只是界限符,字符常量只能是一个字符,不包括单撇号。'a'
和'A'
是不同的字符常量。字符常量存储在计算机存储单元中时,并不是存储字符(如 a,z,# 等)本身,而是以其代码(一般采用 ASCII 代码)存储的,例如字符a
的 ASCII 化代码是 97,因此,在存储单元中存放的是 97(以二进制形式存放)。ASCII 字符与代码对照表见附录 B。 - 转义字符,除了以上形式的字符常量外,C 还允许用一种特殊形式的字符常量,就是以字符
\
开头的字符序列。例如,前面已经遇到过的,在 printf 函数中的'\n'
它代表一个“换行”符。'\t'
代表将输出的位置跳到下一个 tab 位置(制表位置),一个 tab 位置为 8 列。这是一种在屏幕上无法显示的“控制字符”,在程序中也无法用一个一般形式的字符来表示,只能采用这样的特殊形式来表示。
常用的以\
开头的特殊字符见表 3.1。
表 3.1 中列出的字符称为 转义字符,意思是将\
后面的字符转换成另外的意义。如\n
中的 n 不代表字母 n 而作为 换行 符。
表 3.1 中倒数第 2 行是一个以八进制数表示的字符,例如'\101'
代表八进制数 101 的 ASCII 字符,即'A'
(八进制数 101 相当于十进制数 65,从附录 B 可以看到 ASCII 码(十进制数)为 65 的字符是大写字母A
)。'\012'
代表八进制数 12(即十进制数的 10)的 ASCII 码所对应的字符“换行”符。表 3.1 中倒数第 1 行是一个以十六进制数表示的 ASCII 字符,如'\x41'
代表十六进制数 41 的 ASCII 字符,也是'A'
(十六进制数 41 相当于十进制数 65)。用表 3.1 中的方法可以表示任何可显示的字母字符、数字字符、专用字符、图形字符和控制字符。如'\033'
或'\x1B'
代表 ASCII 代码为 27 的字符,即 ESC 控制符。'\0'
或'\000'
是代表 ASCII 码为 0 的控制字符,即“空操作”字符,它常用在字符串中。
2.1.3 字符串常量
如 "boy","123" 等,用双撇号把若干个字符括起来,字符串常量是双撇号中的全部字符(但不包括双撇号本身)。注意不能错写成 'CHINA'
,'boy'
,'123'
。单撇号内只能包含一个字符,双撇号内可以包含一个字符串。
说明:从其字面形式上即可识别的常量称为“字面常量”或“直接常量”。字面常量是没有名字的不变量。
2.1.4 符号常量
用 #define
指令,指定用一个符号名称代表一个常量。如: #define PI 3.1416 //注意行末没有分号
经过以上的指定后,本文件中从此行开始所有的 PI 都代表 3.1416。在对程序进行编译前,预处理器先对PI进行处理,把所有 PI 全部置换为 3.1416。这种用一个符号名代表一个常量的,称为符号常量。在预编译后,符号常量已全部变成字面常量(3.14159)。
注意:如再用赋值语句给 PI 赋值是错的,例如:
PI = 40;
错误,不能给符号常量赋值。
2.2 变量:变量名和变量类型,变量的赋值和类型转换
2.2.1 变量相关概念
- 变量:代表一个有名字的、具有特定属性的一个存储单元。它用来存放数据,也就是存放变量的值。在程序运行期间,变量的值是可以改变的。
变量必须 先定义,后使用。在定义时指定该变量的名字和类型。一个变量应该有一个名字,以便被引用。请注意区分变量名和变量值这两个不同的概念,图 3.3 中 a 是变量名,3 是变量 a 的值,即存放在变量 a 的内存单元中的数据。 - 变量名:实际上是以一个名字代表的一个存储地址。在对程序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。
- 变量命名的规定:C语言规定标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。
例如,正确的:sum
,_total
,month
,Student_name
,lotus_1_2_3
,BASIC
,li_ling
。错误的:M.D.John
,¥123,3D64
,a>b
。
- 变量命名的规定:C语言规定标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。
2.2.2 变量类型
其中基本类型(包括整型和浮点型)和枚举类型变量的值都是数值,统称为算术类型(arithmetic type)。算术类型和指针类型统称为纯量类型(scalar type), 因为其变量的值是以数字来表示的。枚举类型是程序中用户定义的整数类型。数组类型和结构体类型统称为组合类型(aggregate type) ,共用体类型不属于组合类型,因为在同一时间内只有一个成员具有值。函数类型用来定义函数,描述一个函数的接口,包括函数返回值的数据类型和参数的类型。
不同类型的数据在内存中占用的存储单元长度是不同的,例如,VisualC++ 6.0 为 char 型(字符型)数据分配 1 个字节,为 int 型(基本整型)数据分配 4 个字节,存储不同类型数据的方法也是不同的。
2.2.2.1 整型变量
整型变量:整型数据在内存中以二进制形式存放。如: int i; /* 定义为整型变量 */
、i = 10; /* 给 i 赋以整数 10 */
注意:
- 十进制数 10 的二进制形式为 1010,Turbo C 2.0 和 Turbo C++ 3.0 为一个整型变量在内存中分配 2 个字节的存储单元(不同的编译系统为整型数据分配的字节数是不相同的,VC++ 6.0 则分配 4 个字节)。
- 数值是以补码(complement)表示的。
整形变量分类:
- 有符号基本整型:(signed)int
- 有符号短整型:(signed)short(int)
- 有符号长整型: (signed)long(int)
- 无符号基本整型:unsigned int
- 无符号短整型 *:unsigned short(int)
- 无符号长整型 *:unsigned long(int)
- 整数 13 在内存中实际存放情况:
整型变量的定义:C 规定在程序中所有用到的变量都必须在程序中定义,即强制类型定义。
2.2.2.2 字符型变量
字符变量:用类型符 char 定义字符变量。用来存放字符常量,注意只能放一个字符。一个字符变量在内存中占一个字节。
字符变量的定义形式如下:char c1, c2;
字符变量的赋值形式如下:c1 = 'a'; c2 = 'b';
例子: char c = '?';
定义 c 为字符型变量并使初值为字符 ?
。?
的 ASCII 代码是 63,系统把整数 63 赋给变量 c。c 是字符变量,实质上是一个字节的整型变量,由于它常用来存放字符。所以称为字符变量。可以把 0~127 之间的整数赋给一个字符变量。
在输出字符变量的值时,可以选择以十进制整数形式输出,或以字符形式输出。
如: printf(" %d %c\n ,c,c);
输出结果是:63 ?
用 "%d" 格式输出十进制整数 63,用 %c 格式用字符形式输出字符 '?'
。
一个字符常量存放到一个字符变量中,实际上并不是把该字符的字型放到内存中去,而是将该字符的相应的 ASCII 代码放到存储单元中。这样使字符型数据和整型数据之间可以通用。
一个字符数据既可以以字符形式输出,也可以以整数形式输出。
2.2.2.3 浮点型变量
浮点型变量分为单精度(float 型)、双精度(double 型)和长双精度型(long double 型)三类形式。
注意:
一个浮点型变量只能保证的有效数字是 7 位有效数字,后面的数字是无意义的,并不准确地表示该数。应当避免将一个很大的数和一个很小的数直接相加或相减,否则就会"丢失"小的数。
2.2.3 变量的赋值
-
C语言允许在定义变量的同时使变量初始化。如:
int a = 3; // 指定a为整型变量,初值为3 float f = 3.56; // 指定f为浮点型变量,初值为3.56 char c = ‘a’; // 指定c为字符变量,初值为‘a’
-
可以使被定义的变量的一部分赋初值。如:
int a,b,c = 5;
表示指定 a、b、c为整型变量,但只对c初始化,c 的初值为5 -
如果对几个变量赋以同一个初值,应写成:
int a = 3,b = 3,c = 3;
表示 a、b、c 的初值都是 3。不能写成∶int a = b = c3;
2.2.4 变量之间的类型转换
整型(包括 int,short,long)、浮点型(包括 float,double)可以混合运算。在进行运算时,不同类型的数据要先转换成同一类型,然后进行运算。 这种类型转换是由系统自动进行的。
2.3 算术表达式:算术运算符、增量(自增)和减量(自减)运算符、位运算和复合赋值运算符
2.3.1 算术运算符
2.3.2 增量(自增)和减量(自减)运算符
作用是使变量的值增1或减 1。
-
++i,--i(在使用 i 之前,先使 i 的值加 1(减 1)
-
i++,i--(在使用i之后,使i的值加 1(减1)
i++ 与 ++i 的区别:
-
++i 是先执行
i = i + 1;
后,再使用 i 的值; -
i++ 是先使用 i 的值后,再执行
i = i + 1;
。
例如:
j = ++i;
i 的值先变成 4,再赋给 j,j 的值均为 4。j = i++;
先将 i 的值 3 赋给 j,j 的值为 3,然后 i 变为 4。
注意:
- 自增运算符(++),自减运算符(--),只能用于变量,而不能用于常量或表达式,
- ++ 和 -- 的结合方向是「自右至左」。
- 自增(减)运算符常用于循环语句中使循环变量自动加1。也用于指针变量,使指针指向下一个地址。
2.3.3 位运算
位运算:指按二进制位进行的运算。
C语言提供的位运算符有:
-
&
按位与:如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。
即:0 & 0 = 0,0 & 1 = 0,1 & 0 = 0,1 & 1 = 1。 -
~
取反:单目(元)运算符,用来对一个二进制数按位取反,即将0变1,将1变0。 -
|
按位或:两个相应的二进制位中只要有一个为1,该位的结果值为1。
即:0 | 0 = 0,0 | 1 = 1,1 | 0 = 1,1 | 1 = 1。 -
<<
左移:将一个数的各二进制位全部左移若干位。
比如:int a = 1; a <<= 2;
-
>>
右移:将一个数的各二进制位全部右移若干位。移到右端的低位被舍弃,对无符号数、高位补 0。 -
^
按位异或:若参加运算的两个二进制位同号则结果为0(假),异号则结果为1(真)
即:0 ^ 0 = 0,0 ^ 1 = 1,1 ^ 0 = 1,1 ^ 1 = 0。
位运算赋值运算符:位运算符与赋值运算符可以组成复合赋值运算符。例如:&=
,|=
,>>=
,<<=
,∧=
。
注意:
位运算符中除~以外,均为二目(元)运算符,即要求两侧各有一个运算量。
运算量只能是整型或字符型的数据,不能为实型数据。
2.3.4 复合赋值运算符
10 种复合赋值运算符:+=
,-=
,*=
,/=
,%=
,<<=
,>>=
,&=
,^=
,|=
。
例如:
a += 3 等价于 a = a + 3
x *= y+8 等价于 x = x * (y+8)
x %= 3 等价于 x = x % 3
2.4 强制类型转换
可以利用强制类型转换运算符将一个表达式转换成所需类型。
一般形式:(类型名)(表达式)
例如:
-
(double) a 将 a 转换成 double 类型
-
(int)(x+y) 将 x+y 的值转换成整型
-
(float)(5%3) 将 5%3 的值转换成 float 型
注意:
有两种类型转换,一种是在运算时不必用户指定,系统自动进行的类型转换,如 3+6.5。第二种是强制类型转换。当自动类型转换不能实现目的时,可以用强制类型转换。
2.5 数据输入 / 输出函数
在调用标准输入输出库函数时,文件开头应该有:#include "stdio.h"
或:#include <stdio.h>
。
2.5.1 字符输出函数
putchar(c)
:向终端输出一个字符。
2.5.2 字符输入函数
getchar
:从终端(或系统隐含指定的输入设备)输入一个字符。返回函数值为从输入设备得到的字符。
2.5.3 格式输出函数
-
printf(格式控制,输出列表)
:向终端(或系统隐含指定的输出设备)输出若干个任意类型的数据。 -
对应格式控制符:
%d
:以带符号的十进制形式输出整数。%md
:m 为指定的输出字段的宽度。如果数据的位数小于 m,则左端补以空格,若大 m,则按实际位数输出。%ld
:输出长整型数据。
%o
:以八进制无符号形式输出整数。输出的数值不带符号,符号位也一起作为八进制数的一部分输出。%lo
:以八进制无符号形式输出长整数。%mo
:以八进制无符号形式输出指定字段宽度为 m 的整数。
%x
:以十六进制无符号形式输出整数。同样不会出现负的十六进制数。%u
:以无符号十进制形式输出整数。- 一个有符号整数(int 型)也可以用
%u
格式输出;一个 unsigned 型数据也可以用%d
格式输出。unsigned 型数据也可用%o
或%x
格式输出。
- 一个有符号整数(int 型)也可以用
%c
:以字符形式输出,只输出一个字符。- 一个整数,只要它的值在 0 ~ 255 范围内,可以用
%c
使之按字符形式输出,在输出前,系统会将该整数作为 ASCII 码转换成相应的字符;一个字符数据也可以用整数形式输出。
- 一个整数,只要它的值在 0 ~ 255 范围内,可以用
%s
:输出字符串。%s
。例如:printf("%s", "CHINA");
输出字符串 "CHINA"(不包括双引号)。%ms
。输出的字符串占 m 列,若串长大于 m,则全部输出,若串长小于 m,则左补空格。%-ms
。若串长小于 m,字符串向左靠,右补空格。%m.ns
。输出占 m 列,只取字符串中左端 n 个字符,输出在 m 列的右侧,左补空格。%-m.ns
。n 个字符输出在 m 列的左侧,右补空格,若 n > m,m 自动取 n 值。
%f
:以小数形式输出单,双精度数,隐含输出六位小数。%f
。不指定字段宽度,由系统自动指定字段宽度,使整数部分全部输出,并输出 6 位小数。应当注意,在输出的数字中并非全部数字都是有效数字。单精度实数的有效位数一般为 7 位。%m.nf
。指定输出的数据共占 m 列,其中有 n 位小数。如果数值长度小于 m,则左端补空格。%-m.nf
。与%m.nf
基本相同,只是使输出的数值向左端靠,右端补空格。
%e
:以指数形式输出实数。%e
。不指定输出数据所占的宽度和数字部分的小数位数。%m.ne
和%-m.ne
。m、n 和-
字符的含义与前相同。此处 n 指拟输出的数据的小数部分(又称尾数)的小数位数。
%g
:选用%f
或%e
格式中输出宽度较短的一种格式,不输出无意义的 0。
-
几种常见的格式符的修饰符:
L
:用于长整型整数,可加在格式符d
,o
,x
,u
前面M
(代表一个正整数):数据最小宽度N
(代表一个正整数):对实数,表示输出n位小数;对字符串,表示截取的字符个数-
:输出的数字或字符在域内向左靠
注意:
- 除了 X,E,G 外,其他格式字符必须用小写。
- 可以在 printf 函数中的 "格式控制" 字符串中包含转义字符。
- 一个格式说明必须以
%
开头,以 9 个格式字符之一为结束,中间可以插入附加格式字符。- 想输出
%
,则应该在格式控制字符串中用连续两个%
表示
2.5.4 格式输入函数
scanf(格式控制,地址列表)
:按照变量在内存的地址将变量值存进去。- 地址列表是由若干个地址组成的表列,可以是变量的地址,或字符串的首地址。
注意:
- 对 unsigned 型变量所需要的数据,可以用
%u
,%d
或%o ,
%x` 格式输入。- 可以指定输入数据所占的列数,系统自动按它截取所需数据。
- 如果在
%
后有一个*
附加说明符,表示跳过它指定的列数。- 输入数据时不能规定精度。
- scanf 函数中的 "格式控制" 后面应当是变量地址,而不应是变量名。
- 如果在“格式控制”字符串中除了格式说明以外还有其他字符,则在输入数据时在对应位置应输入与这些字符相同的字符。
- 在用 "%c" 格式输入字符时,空格字符和 "转义字符" 都作为有效字符输入。
- 在输入数据时,遇以下情况时认为该数据结束。
- 遇空格,或按“回车”或“跳格”(Tab)键;
- 按指定的宽度结束,如“%3d”,只取3列;
- 遇非法输入。
评论(没有评论)