浅析C指针(一)—概述
C语言提供了指针类型,最直接的作用就是赋予了用户直接读写内存的能力。通过使用指针,可以做到:
- 以不同方式解释内存中的数据
- 构造复杂的数据结构
- ……
上面是我自己对指针的一点理解,下面引用 K&R中的一段话:
A pointer is a variable that contains the address of a variable. Pointers are much used in C, partly because they are sometimes the only way to express a computation, and partly because they usually lead to more compact and efficient code than can be obtained in other ways.
可以看到,K&R是从编程语言的角度说明为什么在C中需要指针,一方面是因为指针有时是表达一种计算的唯一方式,另一方面可以使代码更加简洁且高效。然而,正因为指针的强大,写代码用到指针时总会心里一紧,反复仔细检查,生怕出错,正如墨菲定律所说的——会出错的事总会出现,如果你担心某种情况发生,那么它就更有可能发生。所以,K&R中还带了这么一句:
With discipline, however, pointers can also be used to achieve clarity and simplicity.
在标准中是这样描述指针类型的:
A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’.
示意图为:
可见,指针也是有类型的,其类型由它所指向的类型决定。那么,谈指针之前,先复习一下C语言中的类型。
C语言类型
类型,就是如何解读一个数据对象的值。我们知道,在计算机中信息是以位(bit)存储的,而这些位代表什么含义,得通过上下文(context)来获得。类型就是一种上下文,举个简单的例子:对于0x41 这个值,既可以解读为数字65,也可以解读为ASCII码的A。
关于C语言提供的类型的描述在C语言标准中提供了详尽的描述,接下来将结合C标准和K&R简单地描述一下C语言的类型。在这里,将C语言类型大致分为基本类型和派生类型。
基本类型(Basic Types)
基本类型分为:
字符型:char整型:short,int,long int,long long int以及它们的unsigned类型浮点型float,double
C语言的类型实际所能表示的范围由具体环境决定,为了写出移植性更好的代码,需要留意类型的表示范围。这部分书本和网上都有很多讲解,这里就不详细展示。
派生类型(Derived Types)
对于派生类型,在K&R的附录中是这样说的:
Besides the basic types, there is a conceptually infinite class of derived types constructed from the fundamental types in the following ways:
arrays of objects of a given type
functions returning objects of a given type
pointers to objects of a given type
structures containing a seqence of objects of various types
unions capable of containing any one of several objects of various types
In general these methods of constructing objects can be applied recursively
C标准中的描述(第6.2.5节)更详细和形式化。这段话是说,派生类型有5种:数组、函数、指针、结构体、联合体,通过递归(“递归”概念在这里非常重要)地使用这5种构造对象的方式,从而可以构造概念上无限种类的对象。
- 数组类型:数组是由其元素的类型(element type)派生出来的类型,其属性为
元素类型和数组大小,即由类型 T 派生出T 数组(array of T)。 - 函数类型:函数类型是由其返回类型派生而来,属性为
返回类型和参数的个数和类型,即由返回类型T派生出函数类型返回T的函数(function returning T)。要注意的是,由于函数的大小是不确定的,那么由函数再派生出的只能是指针类型(指向函数的指针),而不能是数组、结构体、联合体这些类型。 - 结构体类型:与数组不同的是可以含有不同类型的元素。
- 联合体类型:与结构体不同的是,所有成员重叠(overlap)使用同一块内存。
- 指针类型:可以由上述所有类型派生而来,对于类型T派生而来的
指向T的指针。
可以这样说,基本类型是原子性的,是原料,通过各种派生方式,从而构造出全新的派生类型。
#define MAX_NAME_LENGTH 16
typedef struct Person {
char name[MAX_NAME_LENGTH];
int phoneNo;
}Person;
void call(int phoneNo);
typedef struct Empolyee {
Person person;
int salary;
void (*call)(int);
}Employee;
由上面例子构造出的类型树为:
(To be continue…)
&spm=1001.2101.3001.5002&articleId=44830539&d=1&t=3&u=ba1f5c7305cc4352a40a4c1da53efd55)
189

被折叠的 条评论
为什么被折叠?



