菜鸟求大神帮看代码哪里有错

C语言 码拜 9年前 (2015-05-11) 902次浏览 0个评论
 

#include <stdio.h>
#include <stdlib.h>
#define L sizeof(struct student)
struct student    //定义学生链表结点类型
{
long ID;//学号
char name[12];//姓名
char sex[3];//性别
int age;//年龄
struct student *next;
};
int n;
/************************
函数功能:创建队列式链表
函数参数:无
函数返回值:头指针head
*************************/
struct student *create()
{
struct student *head, *p, *last;
int i;
head = (struct student*)malloc(L);//创建头结点
printf(“请依次输入每一个学生的学号、姓名、性别、年龄:\n”);
scanf_s(“%d”, &head->ID);//输入学号
getchar();
gets_s(head->name, 12);//输入姓名
gets_s(head->sex, 3);//输入性别
scanf_s(“%d”, &head->age);//输入年龄
last = head;//末结点指针last初始化
for (i = 1; i < n; i++)
{
p = (struct student *)malloc(L);//创建新结点
scanf_s(“%d”, &p->ID);//输入学号
getchar();
gets_s(p->name, 12);//输入姓名
gets_s(p->sex, 3);//输入性别
scanf_s(“%d”, &p->age);//输入年龄
last->next = p;//插入链尾
last = last->next;//last指针后移至末结点
}
last->next = NULL;//链表终止延伸
return head;//返回头指针
}
/******************************
函数功能:打印学生链表中的数据
函数参数:头指针head
函数返回值:无
*******************************/
void printlist(struct student *head)
{
struct student *p;
p = head;//指向头结点
printf(“学生数据为:\n”);
while (p != NULL)
{
printf(“%ld %s %s %d\n”, p->ID, p->name, p->sex, p->age);//输出当前结点包含的信息
p = p->next;//指向下一个结点
}
}
/**************************************************
函数功能:删除含有年龄等于输入年龄的结点
函数参数:头指针head;整形变量key,储存输入的年龄
函数返回值:头指针head
**************************************************/
struct student *del(struct student*head)
{
struct student *p, *pre;
int i, key;
    pre=p= head;
printf(“请输入要删除的年龄:\n”);
scanf_s(“%d”, &key);
for (i = 0; i < n;i++)
{
while (key != p->age&&p->next != NULL)
{
pre = p;
p = p->next;
}
if (p->age == key)
{
if (p == head)
head = head->next;
else
pre->next = p->next;
free(p);
}
else
{
printf(“不存在年龄为%d的学生”, key);
break;
}

    return head;//返回节点删除以后的链表的头指针
}
void main()
{
struct student *head;
printf(“请输入学生数:\n”);
scanf_s(“%d”, &n);
head = create();
printlist(head);
head = del(head);
printlist(head);
printf(“\nmission has been completed!\n”);
getchar();
getchar();
}
**********************************************************************************************
实现的功能是创建一个带头结点的单链表,每个节点包含学号姓名性别年龄,然后根据输入的年龄删除对应的结点(可能不止一个)。
问题:vs2013上调试的时候输入删除年龄时,在  “ while (key != p->age&&p->next != NULL)”会出现“0xC0000005:  读取位置 0xFEEEFF02 时发生访问冲突。”的错误。

10分
循环逻辑不对,第一次循环结束后p为空了,你访问它的所指成员是有问题的~
for循环纯粹多余,通过单项链表的指针迭代就能控制循环~
89分
修改如下:

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct student)
struct student    //定义学生链表结点类型
{
	long ID;//学号
	char name[12];//姓名
	char sex[3];//性别
	int age;//年龄
	struct student *next;
};
int n;
/************************
函数功能:创建队列式链表
函数参数:无
函数返回值:头指针head
*************************/
struct student *create()
{
	struct student *head, *p, *last;
	int i;
	head = (struct student*)malloc(LEN);//创建头结点
	//printf("请依次输入每一个学生的学号、姓名、性别、年龄:\n");
	//scanf_s("%d", &head->ID);//输入学号
	//getchar();
	//gets_s(head->name, 12);//输入姓名
	//gets_s(head->sex, 3);//输入性别
	//scanf_s("%d", &head->age);//输入年龄
	last = head;//末结点指针last初始化
	for (i = 0; i < n; i++)
	{
		p = (struct student *)malloc(LEN);//创建新结点
		printf("请依次输入学生%2d的学号、姓名、性别、年龄:\n", i);
		scanf_s("%d", &p->ID);//输入学号
		getchar();
		gets_s(p->name, 12);//输入姓名
		gets_s(p->sex, 3);//输入性别
		scanf_s("%d", &p->age);//输入年龄
		last->next = p;//插入链尾
		last = last->next;//last指针后移至末结点
	}
	last->next = NULL;//链表终止延伸
	return head;//返回头指针
}
/******************************
函数功能:打印学生链表中的数据
函数参数:头指针head
函数返回值:无
*******************************/
void printlist(struct student *head)
{
	struct student *p;
	//p = head;//指向头结点
	p = head->next;   //指向第一个节点
	printf("学生数据为:\n");
	while (p != NULL)
	{
		printf("%ld %s %s %d\n", p->ID, p->name, p->sex, p->age);//输出当前结点包含的信息
		p = p->next;//指向下一个结点
	}
}
/**************************************************
函数功能:删除含有年龄等于输入年龄的结点
函数参数:头指针head;整形变量key,储存输入的年龄
函数返回值:头指针head
**************************************************/
struct student *del(struct student*head)
{
	struct student *p, *pre;
	int i, key;
	//pre = p = head;
	pre = head;
	p = head->next;
	if (NULL == p)
	{
		printf("空链表无法删除\n");
		return head;
	}
	printf("请输入要删除的年龄:");
	scanf_s("%d", &key);
	//for (i = 0; i < n; i++)
	while(p)
	{
		while (key != p->age && p->next != NULL)
		{
			pre = p;
			p = p->next;
		}

		if (p->age == key)
		{
			/*  既然是带了头节点,就不需要这样操作了
			if (p == head)
				head = head->next;
			else
				pre->next = p->next;
				*/
			pre->next = p->next;   //只用这一句就行
			free(p);
			p = pre->next;
		}
		else
		{
			printf("不存在年龄为%d的学生", key);
			break;
		}
	}
	return head;//返回节点删除以后的链表的头指针
}
int main()
{
	struct student *head;
	printf("请输入学生数:\n");
	scanf_s("%d", &n);
	head = create();
	printlist(head);
	head = del(head);
	printlist(head);
	printf("\nmission has been completed!\n");
	getchar();
	getchar();
	return 0;
}
运行:
菜鸟求大神帮看代码哪里有错
1分
p指针为空了
引用 3 楼 zhangxiangDavaid 的回复:

修改如下:

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct student)
struct student    //定义学生链表结点类型
{
	long ID;//学号
	char name[12];//姓名
	char sex[3];//性别
	int age;//年龄
	struct student *next;
};
int n;
/************************
函数功能:创建队列式链表
函数参数:无
函数返回值:头指针head
*************************/
struct student *create()
{
	struct student *head, *p, *last;
	int i;
	head = (struct student*)malloc(LEN);//创建头结点
	//printf("请依次输入每一个学生的学号、姓名、性别、年龄:\n");
	//scanf_s("%d", &head->ID);//输入学号
	//getchar();
	//gets_s(head->name, 12);//输入姓名
	//gets_s(head->sex, 3);//输入性别
	//scanf_s("%d", &head->age);//输入年龄
	last = head;//末结点指针last初始化
	for (i = 0; i < n; i++)
	{
		p = (struct student *)malloc(LEN);//创建新结点
		printf("请依次输入学生%2d的学号、姓名、性别、年龄:\n", i);
		scanf_s("%d", &p->ID);//输入学号
		getchar();
		gets_s(p->name, 12);//输入姓名
		gets_s(p->sex, 3);//输入性别
		scanf_s("%d", &p->age);//输入年龄
		last->next = p;//插入链尾
		last = last->next;//last指针后移至末结点
	}
	last->next = NULL;//链表终止延伸
	return head;//返回头指针
}
/******************************
函数功能:打印学生链表中的数据
函数参数:头指针head
函数返回值:无
*******************************/
void printlist(struct student *head)
{
	struct student *p;
	//p = head;//指向头结点
	p = head->next;   //指向第一个节点
	printf("学生数据为:\n");
	while (p != NULL)
	{
		printf("%ld %s %s %d\n", p->ID, p->name, p->sex, p->age);//输出当前结点包含的信息
		p = p->next;//指向下一个结点
	}
}
/**************************************************
函数功能:删除含有年龄等于输入年龄的结点
函数参数:头指针head;整形变量key,储存输入的年龄
函数返回值:头指针head
**************************************************/
struct student *del(struct student*head)
{
	struct student *p, *pre;
	int i, key;
	//pre = p = head;
	pre = head;
	p = head->next;
	if (NULL == p)
	{
		printf("空链表无法删除\n");
		return head;
	}
	printf("请输入要删除的年龄:");
	scanf_s("%d", &key);
	//for (i = 0; i < n; i++)
	while(p)
	{
		while (key != p->age && p->next != NULL)
		{
			pre = p;
			p = p->next;
		}

		if (p->age == key)
		{
			/*  既然是带了头节点,就不需要这样操作了
			if (p == head)
				head = head->next;
			else
				pre->next = p->next;
				*/
			pre->next = p->next;   //只用这一句就行
			free(p);
			p = pre->next;
		}
		else
		{
			printf("不存在年龄为%d的学生", key);
			break;
		}
	}
	return head;//返回节点删除以后的链表的头指针
}
int main()
{
	struct student *head;
	printf("请输入学生数:\n");
	scanf_s("%d", &n);
	head = create();
	printlist(head);
	head = del(head);
	printlist(head);
	printf("\nmission has been completed!\n");
	getchar();
	getchar();
	return 0;
}

多谢大神,终于知道错在哪里啦!问题已解决

引用 1 楼 mscf 的回复:

循环逻辑不对,第一次循环结束后p为空了,你访问它的所指成员是有问题的~

嗯呐!是的!现在我明白了!谢谢啦!


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明菜鸟求大神帮看代码哪里有错
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!