浅析C指针(一)

来源:互联网 发布:怎么分析一只股票数据 编辑:程序博客网 时间:2024/05/22 07:06

浅析C指针(一)—概述

  • 浅析C指针一概述
    • C语言类型
      • 基本类型Basic Types
      • 派生类型Derived Types

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 16typedef 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…)

0 0