本章描述数据的各种类型,描述它的特点以及如何声明它,还将描述变量的三个属性——作用域、链接属性和存储类型。
1.基本数据类型
C语言中仅有四种基本数据类型——整型、浮点型、指针和聚合类型(如数组和结构等)。
1)整型家族:字符、短整型、整型和长整型,它们都分为有符号和无符号两种版本。规定整型值相互之间大小的规则很简单——长整型至少应该和整型一样长,而整型至少应该和短整型一样长。 整型字面值 & 枚举类型。
2)指针:指针可以有效地实现诸如tree和list这类高级数据结构。变量的值存储于计算机的内存中,每个变量都占据一个特定的位置。每个内存位置都由地址唯一确定并引用。指针只是地址的另一个名字罢了,指针变量就是一个其值为另一个(一些)内存地址的变量。C语言拥有一些操作符可以获得变量的地址,也可以通过一个指针变量取得它所指向的值或数据结构。指针常量 & 字符串常量。
2.基本声明
1)初始化:如 int j=15;
2)声明简单数组:int vakues[20];注意编译器并不检查程序对数组下标的引用是否在数组的合法范围之内。
3)声明指针:int *a; char *message; message="Hello world";
4)隐式声明:编译器隐式推断声明类型,实际应用中我们并不推荐使用隐式声明;
3.typedef
C语言支持一种叫做typedef的机制,它允许你为各种数据类型定义新名字。
typedef char *ptr_to_char;//把标识符ptr_to_char作为指向字符的指针类型新名字
ptr_to_char a;//声明a是一个指向字符的指针
使用typedef声明类型可以减少使声明变得又臭又长的危险,尤其是那些复杂的声明。
4.常量
使用const关键字来声明常量:
int const a;
const int a;
//由于a的值无法修改,所有无法把任何值赋值给它,有两种方法:
//1.可以在声明时对它进行初始化
int const a=15;
//2.在函数中声明为const形参,在函数被调用时会得到实参的值
//指针变量个它所指向的实体
int *pi;
int const *pi;//一个指向整型常量的指针,你可以修改指针的值,但不能修改它所指向的值
int *const cpi;//一个指向整型的常量指针,指针是常量,它的值无法修改,但可以修改它所指向的整型的值
int const *const cpci;//无论是指针本身还是它所指向的值都是常量,不允许修改
5.作用域
当变量在程序的某个部分被声明时,它只有在程序的一定区域才能被访问。这个区域由标识符的作用域决定,标识符的作用域就是程序中该标识符可以被使用的区域。
编译器可以确认4种不同类型的作用域——文件作用域、函数作用域、代码块作用域和原型作用域。
6.链接属性
标识符的链接属性决定如何处理在不同文件中出现的标识符。标识符的作用域与它的链接属性有关,但这两个属性并不相同。链接属性一共3种——external(外部)、internal(内部)和none(无)。没有链接属性的标识符总是被当做单独的个体,也就是说该标识符的多个声明被当做独立不同的实体。属于internal链接属性的标识符在同一个源文件内的所有声明中都指向一个实体,但位于不同源文件的多个声明则分属不同的实体。最后属于external链接属性的标识符不论声明多少次、位于几个源文件都表示同一个实体。关键字extern和static用于在声明中修改标识符的链接属性。
7.存储类型
变量的存储类型是指存储变量值的内存类型。变量的存储类型决定变量何时创建、何时销毁以及它的值保存多久。有三个地方可以用于存储变量:普通内存、运行时堆栈和硬件寄存器。
变量的缺省存储类型取决于它的声明位置。凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态(static)变量。在代码块内部声明的变量的缺省存储类型是自动的,也就是说它存储于堆栈中,称为自动变量。注意修改变量的存储类型并不表示修改该变量的作用域,它仍然只能在该代码块内部按名字访问。函数的形式参数不能声明为静态,因为实参总是在堆栈中传递给函数,用于支持递归。最后关键字register可以用于自动变量的声明,提示它们应该存储于机器的硬件寄存器而不是内存中,这类变量称为寄存器变量。
8.static关键字
当它用于函数定义时,或用于代码块之外的变量声明时,static关键字用于修改标识符的链接属性,从external改为internal,但标识符的存储类型和作用域不受影响。用这种方式声明的函数或变量只能在声明它们的源文件中访问。
当它用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。
9.总结
具有external链接属性的实体在其它语言的术语里称为全局(globa)实体,所有源文件中的所有函数均可以访问它。只要变量并非声明与代码块或函数定义内部,它在缺省情况下的链接属性即为external。具有external链接属性的实体总是具有静态存储类型。局部变量由函数内部使用,不能被其它函数通过名字引用。它在缺省情况下的存储类型为自动,这是基于连个原因:其一,当这些变量需要时才为它们分配存储,这样可以减少内存的总需求量;其二,在堆栈上为它们分配存储可以有效地实现递归。
10.警告的总结
1)在声明指针变量时采用容易误导的写法;
2)误解指针声明中初始化的含义;
11.编程提示的总结
1)为了保持最佳的可移植性,把字符的值限制在有符号和无符号字符范围的交集之内,或者不要在字符上执行算术运算;
2)用它们在使用时最自然的形式来表示字面值;
3)不要把整型值和枚举值混在一起使用;
4)不要依赖隐式声明;
5)在定义类型的新名字时,使用typedef而不是define;
6)用const声明其值不会修改的变量;
7)使用名字常量而不是字面值常量;
8)不要在嵌套的代码块之间使用相同的变量名;