今天本来想写段代码练练手,想法挺好结果,栽了个大跟头,在这个错误上徘徊了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[] = {
/* 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 < 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;
}

就可以了

大家引以为戒.

C语言顺序表的实现的更多相关文章

  1. C++语言------顺序表实现,用动态数组的方法

    C++ 中常用的一些东西,通过使用动态数组来实现顺序表, 掌握了一下知识点: 1.预处理有三中方法 宏定义,文件包含,条件编译 2.使用同名的变量时,可以在外层使用命名空间 类解决变量名重定义的错误 ...

  2. C语言——顺序表插入、删除、定位运算算法

    说明:将元素x插入到顺序表L的第i个数据元素之前,这个i是从1开始的,但是程序中数组都是从0算起的,不要混淆了. 头文件: header.h // 顺序表的结构定义 #define Maxsize 1 ...

  3. C语言顺序表

    顺序表结构可设为一个数组和一个指向尾部的变量,数组用来存放元素,指向尾部的变量在插入元素的时候加一,删除元素的时候减一,始终指向尾部. typedef int elemtype; typedef st ...

  4. c语言-顺序表

    在数据结构中包含两种,一种线性结构(包括顺序表,链表,栈,队列),一种非线性结构(树,图), 顺序表,其实就是在内存动态数组,Java中的ArrayList就是一个典型的顺序表,它在顺序表的基础上增加 ...

  5. 数据结构C语言顺序表

    #include <stdio.h> #include <stdlib.h> typedef int EmenType; typedef struct Node { int d ...

  6. 数据结构C语言版--动态顺序表的基本功能实现(二)

    /* * 若各个方法结构体变量参数为: &L(即地址符加变量)则结构体变量访问结构成员变量时使用"." * 若为:*L(即取地址符加变量)则结构体变量访问结构体成员变量使用 ...

  7. C语言实现顺序表

    C语言实现顺序表代码 文件SeqList.cpp #pragma warning(disable: 4715) #include"SeqList.h" void ShowSeqLi ...

  8. 数据结构与算法之顺序表C语言实现

    顺序表等相关概念请自行查阅资料,这里主要是实现. 注: 1.顺序表C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简单函数,可自行添加功能: 4.可用C+ ...

  9. c语言进阶12-线性表之顺序表

    一.  线性表的定义 为什么要学习线性表呢? 因为我们日常生活中存在种数据关系,计算机程序是为了解决日常生活的数据关系,因此我们要学习线性表. 线性表是什么呢? 线性表是由n个元素组成的有限序列. 需 ...

随机推荐

  1. WCF-netTcpBinding端口共享

    在同一台机器上一个端口在某时刻只能被一个应用程序占用.对于WCF服务来说,如果服务器上有多个服务并且这些服务寄宿在不同的应用程序中,我们需要某种途径来共享它们的端口.下面是一个示例来演示使用TcpBi ...

  2. DataGridView 隔行显示不同的颜色

    两种方法 第一种 DataGridview1.Rows[i].DefultCellStyle.backcolor 第二种 AlternatingRowsDefutCellstyle 属性 获取或设置应 ...

  3. JAVA注释方式

    1.单行(single-line)注释    //…… 2.块(block)注释                /*……*/ 3.文档注释                      /**……*/

  4. 7、包装类、System、Math、Arrays、大数据运算

    基本类型封装 基本数据类型对象包装类概述 *A:基本数据类型对象包装类概述 *a.基本类型包装类的产生 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需要把字 ...

  5. Restful架构思想

    java作为一门后端语言,其厉害之处在于web,大家比较熟知的各种网络应用,java都能做,那么在这个移动优先的时代,如何继续发挥java的强大呢.通常是让java作为一个app的服务端,为app客户 ...

  6. kinect 深度图像去噪算法

    算法设计思路 (1)读取16位深度图像到待处理图像帧组: (2)ROI区域计算 由于kinect 彩色摄像头和红外深度摄像头是存在视角偏差的,经过视角对齐后,得到的深度图像是有黑边的.此处通过取帧组第 ...

  7. 内嵌Jetty输出debug日志

    Slf4jLog logger = new Slf4jLog(); logger.setDebugEnabled(true); Log.setLog(logger); log4j2.xml中配置如下章 ...

  8. CodeForce 614B Gena's Code(水题)

    这道题提醒我两点: 1.break时一定要检查清楚 2.字符串直接赋值一定要注意结束符,最好能用strcpy 以上是debug的惨痛教训 #include <iostream> #incl ...

  9. For循环中由于ajax异步导致的问题解决(增加alert数据正常,去掉alert之后数据错误)

    由于ajax异步请求的机制,for循环运行不会等内部ajax请求结束,而直接循环到最后.解决方法:将for循环里面的请求单独封装一个方法. 个人遇到的问题具体如下 下面这段代码,如果第5行studat ...

  10. csharp:FlowLayoutPanel

    /// <summary> /// 集合添加的控件 /// 涂聚文20150339 /// </summary> public void AddNewTextBox() { P ...