
正文
c语言链表用什么头函数 c语言 链表
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
关于引用链表
我相信,通过我的说明,你会对这个问题完全理解的。
先说第一个问题,到底能不能引用链表?
首先,明确链表是什么东西。在C语言中,一般都是通过指向头节点的指针来表示链表,这个头指针是链表的入口和起点,也代表了整个链表。那么,它本质上是什么,说到底无非是指针变量。在C++中,也可以定义一个类比如叫做SingleList表示单链表类,具体的链表实例是该类的具体对象,此时,链表的本质是什么?是类的对象。
其次,引用是什么东西?引用是C++中引入的东西,C语言中没有,引用是变量的别名,操作引用和操作变量本身是一样的,引用不会分配新的内存空间。
因此,能不能引用链表的问题,就是有没有指针变量的引用、有没有对象的引用这样的问题。显然,指针变量的引用是可以的,有时候甚至是必须的;对象的引用也是如此。所以,答案很显然,可以引用链表!
再来说说第二个问题,要怎么引用链表?
我前面说了,对链表的引用,本质上是对指针变量或对象的引用,不仅是可以的,有时候甚至是必须的。下面我就举个例子。
在C语言中实现链表的时候,一般都会有个 init() 函数,其功能就是对链表进行初始化,简单的动作就是将链表的头指针置位NULL,就构造了一个空链表。所以,该函数的入口参数肯定得有一个链表的头,在函数里面才能将其设置为NULL。假设,我们这样来写,
void init(Node *head)
{
head = NULL;
}
在main函数里面调用的时候,
int main(void)
{
Node *head;
init(head) ; /* 初始化一个空的链表 */
return 0;
}
上面带注释的那句代码执行之后,head 就真的变成NULL了吗?不是吧?你想,Node *head;这一句,head现在是随机值,传给init函数之后,虽然在init()函数内部更改成了NULL,但它修改的是init中的局部变量,仅仅是形参变量而已,其实在函数执行完毕之后,main函数中的head没有任何变化。这就无法实现初始化空链表的功能了。
可行的方案,就是用引用。定义成下面这样
void init( Node * head) 或者用指向指针的指针 void init(Node **phead)
使用引用的时候,main中用init(head)就行了,使用二维指针时,main中要写成init(head);
通过上面的分析,相信你应该很清楚了,如果还有不明白的,欢迎交流。
相关问答
Q1: C语言 创建带头结点的链表
单链表的生成有2种方式:头插法和尾插法。
1、头插法
/*********************************************************************
* 函数名称:linklist *CreateLinklistHead()
* 函数功能:利用头插法创建链表
* 参 数:无
* 返 回 值:创建完链表后的链表头结点
* 说 明:无
*********************************************************************/
extern linklist *CreateLinklistHead()
{
int x, i, nodeNum;
linklist *head, *temp; // 头结点与临时结点
head = (linklist *)malloc(sizeof(linklist)); // 生成表头结点
head-next = NULL; // 给表头结点的指针域赋值
printf("请输入链表中结点的个数:");
scanf("%d", nodeNum);
for(i=1; i=nodeNum; i++)
{
printf("请输入第 %d 个结点的数据:", i);
scanf("%d", x);
temp = (linklist *)malloc(sizeof(linklist)); // 生成新的结点
temp-data = x; // 对新结点的数据域赋值
// 将新结点插到头结点之后
temp-next = head-next;
head-next = temp;
}
return head; // 返回新建链表的头结点
}2、尾插法
/*********************************************************************
* 函数名称:linklist *CreateLinklistRear()
* 函数功能:利用尾插法创建链表
* 参 数:无
* 返 回 值:创建完链表后的链表头结点
* 说 明:无
*********************************************************************/
extern linklist *CreateLinklistRear()
{
int x, i, nodeNum;
linklist *head, *rear, *temp; // 定义头结点、尾结点和临时结点
head = (linklist *)malloc(sizeof(linklist)); // 生成表头结点,表头结点不存放数据
head-next = NULL; // 将表头结点的指针域赋值为NULL
rear = head; // 将表头结点赋值给表尾结点
printf("请输入链表中结点的个数:");
scanf("%d", nodeNum);
for(i=1; i=nodeNum; i++)
{
printf("请输入第 %d 个结点的数据:", i);
scanf("%d", x);
temp = (linklist *)malloc(sizeof(linklist)); // 生成新的结点
temp-data = x; // 新增结点的数据域
temp-next = NULL; // 新增结点的指针域(由于是尾插法,所以插入的结点都在尾部,即指针域为NULL)
rear-next = temp; // 使前一个结点指向新增结点(head-next=temp)
rear = temp; // 将新增结点赋值给尾结点(尾插法,插入的结点在尾部)(rear=head-next)
}
//rear-next = NULL; // 将尾结点的指针域赋值为空(为了方便检验链表是否为空链表)
return head; // 返回头结点
}
Q2: C语言链表 主函数
1、添加头文件"stdio.h"
2、struct student * creat(void),但是你的main函数中返回接收却是用的int*类型。
3、主函数main应当明确声明为void main()
4、最为严重的是:struct student * creat(void) 函数体中使用了局部变量struct student *head; struct student *p1,*p2; 但是函数结束的地方却要返回这些指针,因此返回的值是无效数据。返回时,已经不再作用域了,是无效的空间。建议把这些数据当作输入参数,指针类型的。就可以正确的接收分配的struct student空间以及指针了。
5、struct student * creat(void) 函数体中,临时指针*p1、*p2再函数返回之前应当设置为NULL,避免因为局部变量的作用域结束导致相关的空间被清除。
总之,我建议把struct student * creat(void)定义修改为:
void creat(struct student **head).
以上内容经过调试,可以使用。
==================我的程序,经过完整的调试
#include "stdafx.h"
#include "malloc.h"
#include "stdio.h"
#define NULL 0
#define LEN sizeof(struct student)
struct student
{
long num;
float score;
struct student *next;
};
int n;
void creat(struct student **head) /*定义函数,此函数带回一个指向链表头的指针*/
{
struct student *p1,*p2;
n=0;
do
{
p1=(struct student *)malloc(LEN); /*开辟一个新单元*/
p1-next=NULL;
scanf("%ld,%f",p1-num,p1-score);
if(p1-num==0)
break;
n++;
if(n==1)
*head=p1;
else
p2-next=p1;
p2=p1;
} while(p1-num!=0) ;
p1=NULL;
p2=NULL;
}
void main()
{
struct student *p;
creat(p);
if(p!=NULL)
do
{
printf("%ld %5.1f\n",p-num,p-score);
p=p-next;
}while(p!=NULL);
flushall(); //清除键盘缓冲区,避免输入混淆
getchar(); //等待键盘任意输入,以便观察运算结果
}
看我的回答怎么样?
关于c语言链表用什么头函数和c语言 链表的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







