C-程序一运行就崩溃、、

发布于 2016-11-30 21:48:40 字数 4799 浏览 1234 评论 4

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

归属感 2017-09-27 19:40:12

另外这里的逻辑也有问题:

 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;

...

虐人心 2017-07-11 23:51:43

将结构体data的定义放在函数声明前。
因为函数声明的形参用了结构体data,但是此时还不清楚结构体data的具体定义。

虐人心 2017-04-15 20:52:31

在创建链表的时候就问题了,你应该还没清楚值传递和址传递的区别。如果想再函数内部改变一个函数外部的变量的值,这个时候用到的是址传递,应该用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来调试程序。这样你能对程序的运行更加清楚。

泛泛之交 2017-01-19 00:43:52

大体看了一下,你的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;
}
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文