a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

C語言順序表實現代碼排錯

2020-01-26 15:40:26
字體:
來源:轉載
供稿:網友

今天本來想寫段代碼練練手,想法挺好結果,栽了個大跟頭,在這個錯誤上徘徊了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;
}

就可以了

大家引以為戒.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 美女1区2区3区 | aaa级片 | 精久视频 | 奇米av| 国产精品久久嫩一区二区 免费 | 国产精品视频一区二区三区 | 日韩视频精品 | 久久亚洲国产视频 | 国产精品久久国产精麻豆99网站 | 成人在线看片网站 | 激情视频网站 | 欧美日韩精品综合 | 色片在线免费观看 | 亚洲一二三在线 | 区一区二区三在线观看 | 日本黄色免费大片 | 日日做夜夜操 | 精品自拍视频 | 麻豆色呦呦| 国产干干干 | 日韩一区二区三区在线 | 久在线 | 欧美成人在线网站 | 高清三区 | 久久九九精品久久 | 国产综合精品一区二区三区 | 91精品国产高清一区二区性色 | 亚洲精品久久久一区二区三区 | 国产精品一区二区三 | 亚洲精品乱码久久久久久不卡 | 色婷婷一区二区三区四区 | 国产精品视频免费播放 | 国产成在线观看免费视频 | 成人精品在线视频 | 黄久久久 | 蜜桃久久av | 国产精品丰满对白在线观看 | 成人综合区 | 久久久国产精品视频 | 极品美女一线天 | 国产一区二区精品 |