今天原本想寫段代碼練練手,想法挺好結果,栽了個大跟頭,在這個錯誤上徘徊了4個小時才解決,如今分享出來,給你們提個醒,先貼上代碼:sql
/******************************************** * 文件名稱: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; }
很自得,自認爲寫的很好,運行一下看看,數組
結果徹底出乎意料.ide
好吧!如今分析錯誤!函數
看看main中的定義學習
int ret = 0;
int i = 0;
sqlist slist;
elemtype e;spa
看看初始化函數init_list指針
int init_list(sqlist *L)
{
L = (sqlist *)malloc(sizeof(sqlist)); code
if (NULL == L) {
L = NULL;
return -1;
} sqlite
L->len = 0; blog
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; }
就能夠了
你們引覺得戒.