一、常量与变量

1. 常量

  1. 整形常量
  2. 实型常量

    • 十进制小数形式
    • 指数形式:\(12.34e3\)(代表\(12.34\times 10^3\))
  3. 字符常量

    • 普通字符:用单引号表示,单引号里只能有一个字符。字符变量以 ASCII 代码的形式储存
    • 转义字符

      转义字符字符值输出结果
      \\a警告 alert产生视觉或声音信号
      \\b退格 backspace将光标当前位置后退一个字符
      \\f换页 form feed将光标位置移到下一页开头
      \\n换行将光标位置移到下一行开头
      \\r回车 carriage return将光标位置移到本行开头
      \\t水平制表符将光标位置移到下一个 Tab 位置
      \\v垂直制表符将光标位置移到下一个垂直制表符对齐点
      \\o\\oo\\ooo(其中o代表一个八进制数字)与该八进制码对应的 ASCII 字符
      \\xh[h...](其中 h代表一个十六进制数字)与该十六进制码对应的 ASCII 字符
  4. 字符串:用双引号表示
  5. 符号变量:用 #define 指令,指定用一个符号代表一个常量

    #define PI 3.1416

符号常量不是变量!符号常量不占用内存,只是作为一个临时符号,代表一个值,在预编译后这个符号就不存在了,一次不能对符号变量重新赋值。为与变量名区别,习惯上符号常量用大写字母表示。

2. 变量

变量必须先定义后使用。变量名实际是以一个名字代表的存储地址。编译时,系统给每一个变量名分配对应的内存地址。从表变量中取值,实际上是通过变量名找到对应的内存地址,从该存储单元中读取数据。

3. 常变量

C99 标准允许使用常变量,方法是定义变量时在前面加一个 const,该变量存在期间其值不能改变。

常变量与常量:

  • 常变量具有变量的基本属性:有类型,占存储单元,只是不允许改变值。
  • 常变量是有名字的不变量,常量是无名字的不变量。

常变量与符号变量:

  • 符号变量是预编译指令,它只是用符号常量代表一个字符串,在预编译时仅进行字符替换,编译后符号常量就不存在了(被值代替),符号常量的名字不分配存储单元。
  • 串并联占用存储单元,有变量值,只是不能改变。
  • 从使用上看,常变量具有符号变量的优点,而且使用更方便,有常变量时可以不使用符号常量。但有些编译系统还未实现 C99 的功能,不能使用常变量。

4. 标识符

用来对常量名、函数、数组、类型等命名的有效字符序列统称为标识符(identifier)。标识符就是一个对象的名字。

C 语言规定标识符只能由字母、下划线、数字组成,且第一个字符必须为字母。大小写字母是两个不同的字符。习惯上变量名使用小写字母。

二、数据类型

类型是指对数据分配存储单元的安排,包括存储单元的长度(占多少字节)一级数据的存储方式。不同的类型分配不同的长度和储存形式。
计算机进行的计算不是抽象的理论值的计算,而是用工程的方法实现的计算,在许多情况下只能得到近似的结果。
C99 允许使用的类型包括:
C语言数据类型
基本类型和枚举类型的变量都是数值,统称为算术类型(arithmetic type)。算术类型和指针类型的变量都是用数字来表示的,统称为纯量类型(scalar type)。枚举类型是程序中用户自定义的整数类型。数组类型和结构体类型统称为组合类型(aggregate type)。共用体类型不属于组合类型,因为在同一时间内只有一个成员具有值。

1. 整形

C 标准没有规定各种类型数据占用的存储单元长度,这是由编译系统自行决定的。如 Turbo C 2.0 为每个 int 分配 2 个字节(16 个二进位),而 Visual C++ 分配 4 个字节(32 个二进位)。C 标准只要求 long 型数据长度不短于 int 型,short 型不长于 int 型,long long 型最长。
可以使用 sizeof(int) 来查看类型或变量的长度。将一个程序移植到另一个系统时,要注意由于编译系统的不同引起的数据溢出。
存储单元存储整数的方法是:使用整数的补码(complement)。

  • 一个正数的补码是其二进制形式。
  • 求负数的补码,先将其绝对值写成二进制形式,让后对其二进制按位取反,再加 1

在储存整数的储存单元中,最左边的一位是用来表示符号的,如果为 0,表示数值为正;如果为 1,表示数值为负。由此可以得到整数型数据的范围(按 Visual C++):

类型字节数取值范围
基本整型 int4\(-2^{31} \sim (2^{31}-1)\)
无符号基本整型 unsigned int4\(0\sim (2^{32}-1)\)
短整型 short2\(-2^{15}\sim (2^{15}-1)\)
无符号短整型 unsigned short2\(0\sim (2^{16}-1)\)
长整型 long4\(-2^{31} \sim (2^{31}-1)\)
无符号长整型 unsigned long4\(0\sim (2^{32}-1)\)
双长型 long long8\(-2^{63}\sim (2^{63}-1)\)
无符号双长型 unsigned long long8\(0\sim (2^{64}-1)\)

修饰符 unsigned 表示无符号类型,即只能取正值。使用 signed 表示有符号类型,通常省略 signed。有符号整形的最高位表示数值的符号,如果指定为无符号类型,则存储单元中所有的二进制位都用来存放数据本身,因此无符号整形可以存放的正数范围比有符号整型扩大一倍。
只有整型数据可以用 signedunsigned 修饰,实型数据不能。无符号整型数据用 %u 格式输出。

2. 字符型

由于字符型是按照其代码形式存储的,因此 C99 把字符型数据作为整型数据的一种。
各种字符集(包括 ASCII 字符集)的基本集都包括 127 个字符:

  • 大小写字母。
  • 数字:0-9。
  • 专门符号 29 个:! & < 等。
  • 空格符:空格、制表符、换行符等。
  • 不能显示的字符:空(null)字符 \0、警告、退格等。

以类型符 char 定义字符变量,可以将 0-127 之间的整数赋值给字符变量,输出时也可以选择以十进制整数形式或字符形式输出。

char c;
c = 64;
printf("%d %c\n", c, c);

// 64 @

字符类型属于整数类型,可以使用 signedunsigned 修饰。127 个字符可以用 7 个二进位来表示,C 语言中指定用一个字节(8 位)储存一个字符(所有系统都不例外),此时,字节中的第一位置为 0。有些系统提供的字符集拓展到了 255 个字符,此时需要把二进位中不用的那一位用起来,把 char 修改为 unsigned char

3. 浮点型

浮点型数据表示具有小数点的实数。C 语言中实数是以指数的形式放在存储单元的,由于一个实数的的指数形式不止一种,即小数点是可以浮动的,因此称为浮点型。

编译系统位 float 型变量分配 4 个字节,将小数部分和指数部分分别存放,4 个字节(32 位)中小数部分和指数部分分别占多少位由编译系统自行决定。由于用二进制表示一个实数以及存储单元长度有限,因此不可能得到完全精确的值。小数部分位数越多,精度越高;指数部分位数越多,能表示的数据范围越大。float 型数据能得到 6 位有效数字,数值范围为 \(-3.4\times 10^{-38} \sim 3.4 \times 10^{38}\)。

为了扩大能表示的数据范围,用 8 个字节储存一个 double 型数据,可以得到 15 位有效数字,数值范围位\( -1.7\times 10^{-308} \sim 1.7 \times 10^{308} \)。为了提高计算精度,C 语言在进行浮点数的算术运算时,将 float 型数据都自动转为 double 型数据,然后进行运算。

不同的编译系统对 long double 的处理方式不同。Turbo C 对 long double 型分配 16 个字节,而 Visual C++对 long doubledouble 的处理方式一样,都分配 8 个字节。

三、运算符和表达式

C 语言提供以下运算符:

  • 算术运算符:+ - * / % ++ --
  • 关系运算符:> < == >= <= !=
  • 逻辑运算符:! && ||
  • 位运算符:<< >> ~ | ^ &
  • 赋值运算符:=
  • 条件运算符:?:
  • 逗号运算符:,
  • 指针运算符:* &
  • 求字节运算符:sizeof
  • 强制类型运算转换符:(type)
  • 成员运算符:. ->
  • 下标运算符:[]
  • 其他:如函数调用运算符 ()

1. 基本算数运算符

运算符含义
+正号或加法
-负号或减法
*乘号
/除号
%取余

两个实数相除,结果为双精度实数。两个整数相除,结果位整数,舍去小数部分,但如果结果为负数,舍去的方向是不一定的,由编译系统决定。多数编译系统采取“向零取整”的方法,即取整后向零靠拢。

2. 自增自减运算符

自增和自减运算符的作用是使变量的值加 1 或减 1:

  • ++i--i:使用 i 之前,先使 i 的值加(减)1
  • i++i--:使用 i 之后,使 i 的值加(减)1
int i = 3;
printf("%d\t", i++);
printf("%d\n", ++i);

// 3    5

3. 算术表达式与运算符的优先级与结合性

C 语言规定运算符是优先级:如先乘除后加减。

如果一个运算对象两侧的运算符优先级相同,则按规定的“结合方向”处理:算术运算符的结合方向都是自左向右,赋值运算符的结合方向是自右向左。“结合性”是 C 语言独有的特性之一。

4. 不同数据类型的混合运算

  • 运算的两个数中有 floatdouble 时,结果位 double
  • 字符型数据与整型或实型数据进行运算时,会先将字符型转换为整型或实型。

5. 强制类型转换符

使用 (类型)(表达式) 可以将一个表达式强制转换为所需的形式。

(float)(5%3)

Reference:

谭浩强《C程序设计(第五版)》


GVenusLeo
7 声望0 粉丝

开拓之人 - 应许之地