热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

C语言顺序表实现代码排错

这篇文章主要介绍了C语言顺序表实现方法,大家参考使用吧

今天本来想写段代码练练手,想法挺好结果,栽了个大跟头,在这个错误上徘徊了4个小时才解决,现在分享出来,给大家提个醒,先贴上代码:

代码如下:

/********************************************
 * 文件名称:sqlist.h
 * 文件描述:线性表顺序存储演示
 * 文件作者:by Wang.J,in 2013.11.16
 * 文件版本:1.0
 * 修改记录:
*********************************************/
#ifndef __SQLIST_H__
#define __DWLIST_H__

#include
#include
#include

#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[] = {
    /* 0  */    "成功执行,无错误",
    /* 1  */    "函数执行错误",
    /* 2  */    "文件打开错误",
};
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         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         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;
}

就可以了

大家引以为戒.


推荐阅读
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 在使用SQL Server进行动态SQL查询时,如果遇到LIKE语句无法正确返回预期结果的情况,通常是因为参数传递方式不当。本文将详细探讨这一问题,并提供解决方案及相关的技术背景。 ... [详细]
  • 本文介绍如何通过创建替代插入触发器,使对视图的插入操作能够正确更新相关的基本表。涉及的表包括:飞机(Aircraft)、员工(Employee)和认证(Certification)。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 精选30本C# ASP.NET SQL中文PDF电子书合集
    欢迎订阅我们的技术博客,获取更多关于C#、ASP.NET和SQL的最新资讯和资源。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
author-avatar
勇淑丁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有