不多废话,先上代码,原创。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//生成随机链表
typedef struct node
{
int value;
struct node *next;
}node,*linkList;
void randList(linkList *ls,int len,int MAX_SIZE)
{
//因为这是对原地址数进行操作,需要进行备份!!!!!!!!!!!!!!
linkList bk,p; //保证函数结束后,出入的指针指向不变!
bk=*ls;
srand((unsigned)time(NULL));
int tempLen=0;
while(++tempLen<=len){
p=(linkList)malloc(sizeof(node));
p->value=rand()%MAX_SIZE;
bk->next=p;
bk=p;
}
bk->next=NULL;
}
void traverse(linkList l)
{
l=l->next;
while(l!=NULL)
{
printf("%d\t", l->value);
l=l->next;
}
printf("\n");
}
int main()
{
int len=10,MAX_SIZE=15;
//scanf("%d%d",&len,&MAX_SIZE);
//带头结点的链表
linkList head=(linkList)malloc(sizeof(node));
randList(&head,len,MAX_SIZE);
traverse(head);
}
这本是一个比较简单的问题,但是写了好久。
如果不写自定义函数的话,代码实现非常简单,这里不再赘述。
下面说说实现的细节问题
主要来说就是链表的传参问题,main函数调用时,只有传入指针变量的地址,自定义函数调用后才会对原变量产生作用。
基于这个想法,由于函数调用是传入的指针类型变量的地址,如下:
randList(&head,len,MAX_SIZE);
因此,自定义函数的形参就必须定义为二重指针类型,这里比较难理解,下面我说说我的理解:
由于函数调用是一个值拷贝的过程(c语言是这样,c++貌似还有引用传递),这里可以理解为在形参的位置上定义了一个新的变量,并把它初始化为实参。与一般的定义变量的不同之处在于形参可以和实参的名字一样。
举个例子。
有个交换函数声明:void swap(int *a,int *b);
调用函数语句为swap(&a,&b);
按上面所说,在调用swap函数时,就会发生 int *a=&a int *b=&b
下面形参a的值就是实参a的地址,*a就是实参a的值。b同理
下面说下指针:
就拿上面的代码来说吧。
randList(&head,len,MAX_SIZE);
void randList(linkList *ls,int len,int MAX_SIZE)
ls的值是head的地址,则*ls就是head变量的值即head所保存的地址,则**ls就是指向head所保存地址的值。
附注:linkList和struct node是等价的