在编写链表相关的程序时,为了使程序的可移植性强的特点,建议在插入函数 传入的链表参数为二级指针型,这样该函的返回值定为void,便于接口访问。下面是我的部分程序代码:
#define ELEMENT_TYPE int
typedef struct Node List;
struct Node
{
ELEMENT_TYPE element;
struct Node * next;
};
/* 插入元素到链表中,采用尾部插入的方法 */
void Insert(List** myList, ELEMENT_TYPE x)
{
List* p = *myList;
List* tmp = NULL;
tmp = (List*)malloc(sizeof (List) );
if (NULL == tmp)
{
cout << "Application memory faliure" << endl;
exit(1);
}
tmp->element = x;
tmp->next = NULL;
if (IsEmpty(p))
{
p = tmp;
*myList = p;
}
else
{
while (NULL != p->next)
{
p = p->next;
}
p->next = tmp;
}
}
int main( void )
{
List* g_myList = NULL;
Insert(&g_myList, 1);
return 0;
}
1.为什么采用二级指针作为参数,这里涉及到了函数参数的问题:函数参数为变量,接收过来的只是变量的值,函数的变量有自己的内存空间,与实际参数的地址是不一样的,这就是为什么交换两个变量的值用值传递无法实现的原因。下面是一个说明
int a = 1;
Int b = 2;
Max(a, b); Max函数在未调用之前,
…
void Max(c, d); Max函数在未调用之前,c,d的值是随机值;调用之后,相当于把a的值赋给c,b的值赋给d;而a和c的地址空间是完全不一样的,同b和d的地址空间也是不一样的;大家可以用printf("%d%d%d%d", &a, &c, &b, &d);来验证一下,这样Max函数实际上是交换了两个局部变量的值。
2.对于指针参数
传递给函数参数的还是值,只不过这个值是指针变量的值,对指针变量*操作就是以这个值为地址,获取这个地址上存的数据,这样操作函数的局部变量相当于操作那两块地址空间了,这样就会实现上例中Max的功能了。
3.总以一句话,传递给函数参数的值都是一份拷贝,并不是原来的那个变量(除了引用类型),每个变量都有自己独一无二的地址空间;这样就不难理解,插入链表时传入二级指针参数的原因了。