C语言中最多可以使用几层指针?
对这个问题的回答与“指针的层数”所指的意思有关。如果你是指“在说明一个指针时最多可以包含几层间接引用”,答案是“至少可以有12层”。请看下例:
int i = 0;
int * ip0l = &d;
int ** ip02 = &ip01;
int ***ip03 = &ip02;
int **** ip04 = &dp03;
int ***** ip05 = &ip04;
int ****** ip06 = &ip05;
int ******* ip07 = &ip06;
int ******** ip08 = &ip07;
int ********* ip09 = &ip08;
int **********ip10 = &ip09;
int ***********ipll = &ip10;
int ************ ip12 = &ipll;
************ ip12 = 1; / * i = 1 * /
注意:ANSIC标准要求所有的编译程序都必须能处理至少12层间接引用,而你所使用的编译程序可能支持更多的层数。
如果你是指“最多可以使用多少层指针而不会使程序变得难读”,答案是这与你的习惯有关,但显然层数不会太多。一个包含两层间接引用的指针(即指向指针的指针)是很常见的,但超过两层后程序读起来就不那么容易了,因此,除非需要,不要使用两层以上的指针。
如果你是指“程序运行时最多可以有几层指针”,答案是无限层。这一点对循环链表来说是非常重要的,因为循环链表的每一个结点都指向下一个结点,而程序能一直跟住这些指针。请看下例:
例7.2一个有无限层间接引用的循环链表
/ * Would run forever if you didn't limit it to MAX * /
# include <stdio. h>
struct circ_list
{
char value[ 3 ]; /* e.g.,"st" (incl '\0') */
struct circ_list * next;
};
struct circ_list suffixes[ ] = {
"th" , &.suffixes[ 1 ], / * Oth * /
"st" , &.suffixes[ 2 ], / * 1st * /
"nd" , & suffixes[ 3 ], / * 2nd * /
"rd" , & suffixes[ 4 ], / * 3rd * /
"th", &.suffixes[ 5 ], / * 4th * /
"th" , &.suffixes[ 6 ], / * 5th * /
"th" , & suffixes[ 7 ], / * 6th * /
"th" , & suffixes[ 8 ], / * 7th * /
"th", & suffixes[ 9 ], / * 8th * /
"th" , & suffixes[ 0 ], / * 9th * /
};
# define MAX 20
main()
{
int i = 0;
struct circ_list *p = suffixes;
while (i <=MAX) {
printf("%ds%\n", i, p->value);
+ +i;
p = p->next;
}
}
在上例中,结构体数组suffixes的每一个元素都包含一个表示词尾的字符串(两个字符加上末尾的NULL字符)和一个指向下一个元素的指针,因此它有点象一个循环链表;next是一个指针,它指向另一个circ_list结构体,而这个结构体中的next成员又指向另一个circ_list结构体,如此可以一直进行下去。
上例实际上相当呆板,因为结构体数组suffixes中的元素个数是固定的,你完全可以用类似的数组去代替它,并在while循环语句中指定打印数组中的第(i%10)个元素。循环链表中的元素一般是可以随意增减的,在这一点上,它比上例中的结构体数组suffixes要有趣一些。
int i = 0;
int * ip0l = &d;
int ** ip02 = &ip01;
int ***ip03 = &ip02;
int **** ip04 = &dp03;
int ***** ip05 = &ip04;
int ****** ip06 = &ip05;
int ******* ip07 = &ip06;
int ******** ip08 = &ip07;
int ********* ip09 = &ip08;
int **********ip10 = &ip09;
int ***********ipll = &ip10;
int ************ ip12 = &ipll;
************ ip12 = 1; / * i = 1 * /
注意:ANSIC标准要求所有的编译程序都必须能处理至少12层间接引用,而你所使用的编译程序可能支持更多的层数。
如果你是指“最多可以使用多少层指针而不会使程序变得难读”,答案是这与你的习惯有关,但显然层数不会太多。一个包含两层间接引用的指针(即指向指针的指针)是很常见的,但超过两层后程序读起来就不那么容易了,因此,除非需要,不要使用两层以上的指针。
如果你是指“程序运行时最多可以有几层指针”,答案是无限层。这一点对循环链表来说是非常重要的,因为循环链表的每一个结点都指向下一个结点,而程序能一直跟住这些指针。请看下例:
例7.2一个有无限层间接引用的循环链表
/ * Would run forever if you didn't limit it to MAX * /
# include <stdio. h>
struct circ_list
{
char value[ 3 ]; /* e.g.,"st" (incl '\0') */
struct circ_list * next;
};
struct circ_list suffixes[ ] = {
"th" , &.suffixes[ 1 ], / * Oth * /
"st" , &.suffixes[ 2 ], / * 1st * /
"nd" , & suffixes[ 3 ], / * 2nd * /
"rd" , & suffixes[ 4 ], / * 3rd * /
"th", &.suffixes[ 5 ], / * 4th * /
"th" , &.suffixes[ 6 ], / * 5th * /
"th" , & suffixes[ 7 ], / * 6th * /
"th" , & suffixes[ 8 ], / * 7th * /
"th", & suffixes[ 9 ], / * 8th * /
"th" , & suffixes[ 0 ], / * 9th * /
};
# define MAX 20
main()
{
int i = 0;
struct circ_list *p = suffixes;
while (i <=MAX) {
printf("%ds%\n", i, p->value);
+ +i;
p = p->next;
}
}
在上例中,结构体数组suffixes的每一个元素都包含一个表示词尾的字符串(两个字符加上末尾的NULL字符)和一个指向下一个元素的指针,因此它有点象一个循环链表;next是一个指针,它指向另一个circ_list结构体,而这个结构体中的next成员又指向另一个circ_list结构体,如此可以一直进行下去。
上例实际上相当呆板,因为结构体数组suffixes中的元素个数是固定的,你完全可以用类似的数组去代替它,并在while循环语句中指定打印数组中的第(i%10)个元素。循环链表中的元素一般是可以随意增减的,在这一点上,它比上例中的结构体数组suffixes要有趣一些。