33,311
社区成员
发帖
与我相关
我的任务
分享
我们应该注意,指针只能指向某种特定类型的对象,也就是说,每个指针都必须指向某 种特定的数据类型。(一个例外情况是指向 void 类型的指针可以存放指向任何类型的指针, 但它不能间接引用其自身。我们将在 5.11 节中详细讨论该问题)。
如果指针 ip 指向整型变量,那么在 x 可以出现的任何上下文中都可以使用*ip,因此,
语句
*ip = *ip + 10;
将把*ip 的值增加 10。 一元运算符*和&的优先级比算术运算符的优先级高,因此,赋值语句
y = *ip + 1
将把*ip 指向的对象的值取出并加 1,然后再将结果赋值给 y,而下列赋值语句:
*ip += 1
则将 ip 指向的对象的值加 1,它等同于
++*ip
或
(*ip)++
语句的执行结果。语句(*ip)++中的圆括号是必需的,否则,该表达式将对 ip 进行加 1 运算, 而不是对 ip 指向的对象进行加 1 运算,这是因为,类似于*和++这样的一元运算符遵循从右 至左的结合顺序。
最后说明一点,由于指针也是变量,所以在程序中可以直接使用,而不必通过间接引用 的方法使用。例如,如果 iq 是另一个指向整型的指针,那么语句
iq = ip
将把 ip 中的值拷贝到 iq 中,这样,指针 iq 也将指向 ip 指向的对象。
5.1. 指针与地址
首先,我们通过一个简单的示意图来说明内存是如何组织的。通常的机器都有一系列连 续编号或编址的存储单元,过些存储单元可以单个进行操纵,也可以以连续成组的方式操纵。 通常情况下,机器的一个字节可以存放一个 char 类型的数据,两个相邻的字节存储单元可存 储一个 short(短整型)类型的数据,而 4 个相邻的字节存储单元可存储一个 long(长整型) 类型的数据。指针是能够存放一个地址的一组存储单元(通常是两个或 4 个字节)。因此,如 果 c 的类型是 char,并且 p 是指向 c 的指针,则可用图 5-1 表示它们之间的关系:
图 5-1
一元运算符&可用于取一个对象的地址,因此,下列语句:
p = &c;
将把 c 的地址赋值给变量 p,我们称 p 为"指向”c 的指针。地址运算符&只能应用于内存中 的对象,即变量与数组元素。它不能作用于表达式、常量或 register 类型的变量。
一元运算符*是间接寻址或间接引用运算符。当它作用于指针时,将访问指针所指向的对 象。我们在这里假定 x 与 y 是整数,而 ip 是指向 int 类型的指针,下面的代码段说明了如 何在程序中声明指针以及如何使用运算符&和*:
int x = 1, y = 2, z[10];
int *ip; /* ip is a pointer to int */
ip = &x; /* ip now points to x */
y = *ip; /* y is now 1 */
*ip = 0; /* x is now 0 */
ip = &z[0]; /* ip now points to z[0] */
变量 x、y 与 z 的声明方式我们已经在前面的章节中见到过。我们来看指针 ip 的声明, 如下所示:
int *ip:
这样声明是为了便于记忆。该声明语句表明表达式*ip 的结果是 int 类型。这种声明变量的 语法与声明该变量所在表达式的语法类似。同样的原因,对函数的声明也可以采用这种方式。 例如,声明
double *dp,atof(char *);
表明,在表达式中,*dp 和 atof(s)的值都是 double 类型,且 atof 的参数是一个指向 char
类型的指针。