C-程序一运行就崩溃、、
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define LEN 1000 // 字符数组长度
#define MAX 100 // 共100个数据
#define STRLEN 20 // 每个字符串的长度
struct data{ // 构建一个节点
char str[STRLEN];
struct data *next;
};
bool create_list(struct data *, int); // 创建链表,成功返回true,失败返回false
void initialize_list(struct data *); // 初始化链表
bool check_data(struct data *, char *); // 检查链表中是否有某个数据,存在返回true,反之返回false
bool delete_data(struct data *, int); // 删除链表中偶数位置的数据
void display_data(struct data *, int); // 输出链表中奇数位置的数据
struct data * reverse_list(struct data *); // 反转链表
int main(void)
{
struct data *head = NULL;
struct data *head_copy; // 头节点和头节点副本
// 创建链表
if (!create_list(head, MAX))
{
printf("Create failed.n");
exit(1);
}
// 初始化链表
head_copy = head; // 使用head的副本
initialize_list(head_copy);
/* 删除数据 */
puts("n============================================================");
puts("删除链表中偶数位置的数据:");
if (delete_data(head_copy, MAX))
printf("删除成功!n");
else
printf("删除失败!n");
/*检查100是否在链表中*/
puts("n============================================================");
puts("检查100是否在链表中:");
if (check_data(head_copy, "100"))
puts("100在链表中");
else
puts("100不在链表中");
/* 输出奇数位置的数据 */
puts("n============================================================");
puts("奇数位置的数据:");
display_data(head_copy, MAX);
/* 反转链表 */
puts("n============================================================");
puts("反转链表后奇数位置的数据:");
head = reverse_list(head_copy);
display_data(head, MAX);
return 0;
}
/*创建链表*/
bool create_list(struct data *phead, int n)
{
int i = 0;
phead = (struct data *)malloc(sizeof(struct data));
if (NULL == phead)
return false;
else
{
while (i++ < n)
{
struct data * new = (struct data *)malloc(sizeof(struct data));
if (NULL == new)
{
puts("内存分配失败!");
exit(1);
}
phead->next = new;
phead = new->next;
}
return true;
}
}
/*初始化链表*/
void initialize_list(struct data * phead)
{
FILE *fp;
char ch;
char *pstr;
char numbers[LEN];
int i = 0;
// 打开文件,并把文件中的数据读取到一个字符数组中
if ((fp = fopen("data100.txt", "r")) == NULL)
{
fprintf(stderr, "Can't open the file.");
exit(2);
}
while ((ch = getc(fp)) != EOF)
numbers[i++] = ch;
/* 把数据赋给链表 */
pstr = strtok(numbers, " ");
while (pstr)
{
strcpy(phead->next->str, pstr);
pstr = strtok(NULL, " ");
phead = phead->next;
}
}
/* 删除偶数位置的数据 */
bool delete_data(struct data * phead, int n)
{
int i = 0;
struct data * temp = phead->next;
if (NULL == phead)
return false;
while ((i < n) && phead != NULL)
{
if (i % 2 == 0)
{
phead->next = temp->next;
free(temp);
temp = phead->next->next;
phead = phead->next;
}
i++;
}
return true;
}
/* 检查数据 */
bool check_data(struct data * phead, char * pstr)
{
while (phead)
{
if (strcmp(pstr, phead->next->str) == 0)
return true;
phead = phead->next;
}
return false;
}
/* 输出奇数位置的数据 */
void display_data(struct data * phead, int n)
{
int i = 0;
while (i < n && phead != NULL)
{
if (i % 2 == 1)
{
printf("%s ", phead->next->str);
if (i % 4 == 0)
putchar('n');
}
phead = phead->next;
i++;
}
}
/* 反转链表 */
struct data *reverse_list(struct data *phead)
{
struct data *p_new_head = NULL;
struct data *p_prev = NULL;
struct data *p_next;
while (phead != NULL)
{
p_next = phead->next;
if (p_next == NULL)
p_new_head = phead;
phead->next = p_prev;
p_prev = phead;
phead = p_next;
}
return p_new_head;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
另外这里的逻辑也有问题:
bool delete_data(struct data * phead, int n)
{
int i = 0;
struct data * temp = phead->next;
if (NULL == phead)
return false;
...
应该是先判断phead是否为空, 否则phead为null, phead->next肯定挂了
bool delete_data(struct data * phead, int n)
{
int i = 0;
if (NULL == phead)
return false;
struct data * temp = phead->next;
...
将结构体data的定义放在函数声明前。
因为函数声明的形参用了结构体data,但是此时还不清楚结构体data的具体定义。
在创建链表的时候就问题了,你应该还没清楚值传递和址传递的区别。如果想再函数内部改变一个函数外部的变量的值,这个时候用到的是址传递,应该用head的地址作为参数,来调用create_list(&head, MAX)。
函数内部也需要做适当的调整,如下:
/*创建链表*/
bool create_list(struct data **Phead, int n)
{
int i = 0;
struct data *phead = NULL;
phead = (struct data *)malloc(sizeof(struct data));
if (NULL == phead)
return false;
else
{
while (i++ < n)
{
struct data * new = (struct data *)malloc(sizeof(struct data));
if (NULL == new)
{
puts("内存分配失败!");
exit(1);
}
// phead->next = new;
// phead = new->next;
new->next = phead->next;//采用了头插法,你可以画图理解一下,这两步不能颠倒。
phead->next = new;
}
*Phead = phead;
return true;
}
}
其余的代码我不确定是否还有问题,需要你进一步去验证。
ps:
对了,你还要学会使用printf来调试程序。这样你能对程序的运行更加清楚。
大体看了一下,你的create_list是错的,尤其是这两句:phead->next = new;phead = new->next;你的头结点phead也用错了,按你这样做,链表最终就找不到头结点了;而且你把更要命的是,你把new关键字声明为一个变量,这也太.....。我给你改了一下你的create_list函数,你可以看看。
bool create_list(struct data * &phead, int n)
{
int i = 0;
phead = (struct data *)malloc(sizeof(struct data));
if (NULL == phead)
return false;
else
{
data * q=phead;
while (i++ < n)
{
struct data * newNode = (struct data *)malloc(sizeof(struct data));
if (NULL == newNode)
{
puts("内存分配失败!");
exit(1);
}
q->next = newNode;
newNode->next=NULL;
q=newNode;
}
return true;
}
}