时间:2021-05-20
今天本来想写段代码练练手,想法挺好结果,栽了个大跟头,在这个错误上徘徊了4个小时才解决,现在分享出来,给大家提个醒,先贴上代码:
复制代码 代码如下:
/********************************************
* 文件名称:sqlist.h
* 文件描述:线性表顺序存储演示
* 文件作者:by Wang.J,in 2013.11.16
* 文件版本:1.0
* 修改记录:
*********************************************/
#ifndef __SQLIST_H__
#define __DWLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 50
#define OK 0
#define ERR -1
typedef int elemtype;
typedef struct {
elemtype data[MAXSIZE];
int len;
}sqlist;
int init_list(sqlist *L);
int destroy_list(sqlist *L);
int list_empty(sqlist L);
int list_length(sqlist L);
int disp_list(sqlist L);
int get_elem(sqlist L, int i, elemtype *e);
int local_elem(sqlist L, elemtype e);
int list_insert(sqlist *L, int i, elemtype e);
int list_delete(sqlist *L, int i, elemtype *e);
#endif
/**************************************************
* 文件名称:sqlist.c
* 文件描述:线性表顺序存储的实现
* 文件作者:by Wang.J,in 2013.11.16
* 文件版本:1.0
* 修改记录:
***************************************************/
#include "sqlist.h"
#if 0
#define ERR_NONE_ERROR 0
#define ERR_FUNC_EXEC 1
#define ERR_FILE_OPEN 2
char *error_msg[] = {
"成功执行,无错误",
"函数执行错误",
"文件打开错误",
};
int my_errno = 0;
#endif
int main(void)
{
int ret = 0;
int i = 0;
sqlist slist;
elemtype e;
memset(&slist, 0, sizeof(slist));
printf("length:%d\n", slist.len);
ret = init_list(&slist);
if (OK != ret)
return -1;
ret = list_empty(slist);
printf("长度:%d\n", slist.len);
if (OK == ret)
printf("顺序表为空\n");
if (ERR == ret)
printf("顺序表不为空\n");
for (i = 0; i < 10; i++) {
e = (elemtype)i;
list_insert(&slist, i, e);
}
printf("插入数据\n");
ret = list_empty(slist);
if (OK == ret)
printf("顺序表为空\n");
if (ERR == ret)
printf("顺序表不为空\n");
printf("after length%d\n", list_length(slist));
disp_list(slist);
destroy_list(&slist);
return 0;
}
/*=====================================================
* 函数名称:init_list
* 函数功能:初始化一个顺序表,创建一个空的顺序表
* 函数参数:sqlist *L 负责返回一个创建好的顺序表,如果创建
失败则返回NULL
* 返 回 值:成功返回0并通过指针返回一个创建好的空表
失败返回-1指针返回NULL
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int init_list(sqlist *L)
{
L = (sqlist *)malloc(sizeof(sqlist));
if (NULL == L) {
L = NULL;
return -1;
}
L->len = 0;
return 0;
}
/*=====================================================
* 函数名称:destroy_list
* 函数功能:销毁创建好的顺序表,释放顺序表的空间
* 函数参数:sqlist *L,已经存在的线性表
* 返 回 值:成功 0
失败 -1
通常free不会失败,其实这个函数可以直接使用void
的,这里只是自己顺手写的,看到代码就知道不会返回0
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int destroy_list(sqlist *L)
{
free(L);
return 0;
}
/*=====================================================
* 函数名称:list_empty
* 函数功能:判断sqlist顺序表是否为空
* 函数参数:sqlist L,已存在的线性表
* 返 回 值:空 0
不空 -1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int list_empty(sqlist L)
{
if (0 == L.len)
return 0;
return -1;
}
/*=====================================================
* 函数名称:list_length
* 函数功能:取得线性表的长度,返回顺序表中元素个数
* 函数参数:sqlist L,已经存在的线性表
* 返 回 值:L的长度
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int list_length(sqlist L)
{
return L.len;
}
/*=====================================================
* 函数名称:disp_list
* 函数功能:显示顺序表中所有的元素
* 函数参数:sqlist L,已经存在的线性表
* 返 回 值:成功 0
失败 -1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int disp_list(sqlist L)
{
int i = 0;
if (0 >= L.len)
return -1;
for (i = 0; i < L.len; i++)
printf("%d\t", L.data[i]);
/*
* 这个地方我自己是有异议的,首先你可能不知道输出的类型为
* %d,再就是求长度是使用list_length函数还是使用L.len方式,
* list_length是函数调用有着函数调用的额外开销,在PC上这点
* 开销不算什么,但是在嵌入式系统就不得不考虑这种开销了,
* 这基本上算是良好的移植性和代码效率之间的问题,为了提高
* 移植性可以多添加几层抽象层,实现各种判断.除非是极其庞大
* 的项目或是为了匹配各种这样的设备,我认为像代码定义类型这
* 种小事,团队沟通就能解决.工作是避免问题,学习是自找问题.
* 所以怎么取舍只能看个人了.
*/
printf("\n");
return 0;
}
/*=====================================================
* 函数名称:get_elem
* 函数功能:获取i位置元素的值域,为了方便对应i从0开始与
数组下标一致,用e返回获取的值
* 函数参数:sqlite L 存在的顺序表
int i 位置
elemtype *e 返回值域
* 返 回 值:成功 0
失败 -1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int get_elem(sqlist L, int i, elemtype *e)
{
if (i < 0 || i >= L.len) {
e = NULL;
return -1;
}
*e = L.data[i];
/*
* 这个地方要注意
* 看看与e = &(L.data[i])区别
*/
return 0;
}
/*=====================================================
* 函数名称:local_elem
* 函数功能:按元素值查找,返回第一个与e相匹配的元素位置
* 函数参数:sqlist L,已经存在的顺序表
* 返 回 值:存在返回位置
失败返回-1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int local_elem(sqlist L, elemtype e)
{
int i = 0;
for (i = 0; i < L.len; i++) {
if (e == L.data[i])
return i;
}
return -1;
}
/*=====================================================
* 函数名称:list_insert
* 函数功能:在sqlite的i位置插入元素
* 函数参数:sqlist *L 已存在的顺序表
int i 位置
elemtype e 元素
* 返 回 值:成功 0
失败 -1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int list_insert(sqlist *L, int i, elemtype e)
{
int j = 0;
if (i < 0 || i > MAXSIZE-1)
return -1;
for (j = L->len; j > i; j--)
L->data[j] = L->data[j-1];
L->data[i] = e;
L->len++;
return 0;
}
/*=====================================================
* 函数名称:list_delete
* 函数功能:删除i位置的元素,元素通过e返回
* 函数参数:sqlite *L 已存在的顺序表
int i 位置
elemtype *e 删除位置的元素
* 返 回 值:成功 0
失败 -1
* 创 建 人:by Wang.J,in 2013.11.16
* 修改记录:
======================================================*/
int list_delete(sqlist *L, int i, elemtype *e)
{
int j = 0;
if (i < 0 || i >=L->len)
return -1;
*e = L->data[i];
for (j = i; j < (L->len-1); j++)
L->data[j] = L->data[j+1];
L->len--;
return 0;
}
很自得,自认为写的很好,运行一下看看,
结果完全出乎意料.
好吧!现在分析错误!
看看main中的定义复制代码 代码如下:
int ret = 0;
int i = 0;
sqlist slist;
elemtype e;
看看初始化函数init_list
复制代码 代码如下:
int init_list(sqlist *L)
{
L = (sqlist *)malloc(sizeof(sqlist));
if (NULL == L) {
L = NULL;
return -1;
}
L->len = 0;
return 0;
}
相信聪明的你已经看出来了,我在main中定义的slist空间在栈上,而我在init_list中一下子将这个东东分配到了堆空间,并且slist并不是指针,根本无法进行指向,所以结果当然就非常的错误了.
打个比方,栈和堆是两个平行的世界,只有指针是穿梭于两个世界的虫洞,除此以为其他东西无法进行跨越.
知道了原因自然很容易解决了.
由于栈上会自动分配空间所以就无需再次申请空间.所以init_list改为:
复制代码 代码如下:
int init_list(sqlist *L)
{
/*
L = (sqlist *)malloc(sizeof(sqlist));
if (NULL == L) {
L = NULL;
return -1;
}
*/
L->len = 0;
return 0;
}
就可以了
大家引以为戒.
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C语言实现动态顺序表的实现代码顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存
实现顺序表的插入,删除,查找,输出操作在C语言中经常用到。下面小编给大家整理实现代码,一起看下吧代码如下所示:?123456789101112131415161
本文实例讲述了C语言实现顺序表(线性表)的方法。分享给大家供大家参考,具体如下:一:顺序表代码实现?123456789101112131415161718192
本文实例为大家分享了C语言实现顺序表的顺序查找和折半查找的具体代码,供大家参考,具体内容如下顺序查找:#includeusingnamespacestd;int
本文实例为大家分享了C语言实现顺序表的具体代码,供大家参考,具体内容如下seqlist.h#ifndef__SEQLIST_H__#define__SEQLIS