| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1057 人关注过本帖
标题:请教:我想做一个比较特别的双向列表,指针作加法有点问题,大家帮我看看!
只看楼主 加入收藏
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
我也是Linux环境的牙,我代码改了,主要是去掉了那个NULL,那个是我试验断言用的~~运行代码结果如下:

程序代码:
yiran@yiran-ubuntu:~$ cat test.c 
#include <stdio.h>
#include <assert.h>

struct shm_data_st
{
    struct shm_data_st *pre;
    char data[10];
    struct shm_data_st *next;
};

    struct shm_data_st*
init_shm_data(memory, size)
    void        *memory;
    size_t      size;
{
    struct  shm_data_st *pt = memory;
    struct  shm_data_st *end = memory + size;

    assert(memory != NULL && size != 0);

    for (; pt < end; ++pt)
    {
        pt->pre = pt - 1;
        sprintf(pt->data, "struct %d", pt - (struct shm_data_st*)memory);
        pt->next = pt + 1;
    }

    ((struct shm_data_st*)memory)->pre = NULL;
    pt[-1].next = NULL;

    return memory;
}

int main(void)
{
    char buf[1000];
    struct shm_data_st *pt;

    init_shm_data(buf, 1000);

    for (pt = (struct shm_data_st*)buf;
            pt != NULL;
            pt = pt->next)
        puts(pt->data);

    return 0;
}
yiran@yiran-ubuntu:~$ gcc test.c -o test
yiran@yiran-ubuntu:~$ ./test
struct 0
struct 1
struct 2
struct 3
struct 4
struct 5
struct 6
struct 7
struct 8
struct 9
struct 10
struct 11
struct 12
struct 13
struct 14
struct 15
struct 16
struct 17
struct 18
struct 19
struct 20
struct 21
struct 22
struct 23
struct 24
struct 25
struct 26
struct 27
struct 28
struct 29
struct 30
struct 31
struct 32
struct 33
struct 34
struct 35
struct 36
struct 37
struct 38
struct 39
struct 40
struct 41
struct 42
struct 43
struct 44
struct 45
struct 46
struct 47
struct 48
struct 49
yiran@yiran-ubuntu:~$ 

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-26 03:58
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
恩,在终端下用gcc可以编译,结果也一样,之前我是用的  NetBeans IDE环境  版本比较高可能对语法要求严格,

那句pt[-1].next = NULL到底是什么啊,我在网上也没有找到相关的资料,没有见过 难道 [-1]. 就是等于 -> ,或是 pt-1 别的什么?

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 07:48
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
谢谢 StarWing83 终于弄明白了
程序开始申请了1000字节的空间 buf[1000]
init_shm_data(memory, size)第一个参数是空间的起始地址,size是空间的大小
这个函数里面定义的两个指针用来保证不会访问到 1000 以外的地址
++PT 就已经实现了 pt指向结构体后面的一个字节,就像一个数组一样
    后面两句在初始化,第一个数组的pre 最后一个数组的next
    pt[-1].next = NULL; 这个虽然我没有找到,根据意思就是,pt-1了,
在最后一次移动的时候超过了1000 pt-1,移回最后一个位置。

很巧妙的思想,比起我想的方便多了,不容易错,别人还容易看懂,厉害

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 08:18
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
思想是最重要的,
这个问题让我学到很多,谢谢了StarWing83!

[[it] 本帖最后由 asmdaydream 于 2009-7-26 09:07 编辑 [/it]]

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 08:58
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
呵呵,没关系。你用NetBeans编译的时候,确定程序用的.c的扩展名么NetBeans?NetBeans也是调用gcc进行编译的,关键是让他“认为”是C程序,而不是C++程序。C++程序语法比C严格。

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-26 16:56
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
呵呵,创建的时候是 .c 后缀的,不能编译主要是因为指针类型不同导致的错误,修改一下就好了,最后执行的时候应该就是最后一次访问出现的段错误,因为我通过控制结构体的个数后段错误就没有发生了

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 20:10
StarWing83
Rank: 8Rank: 8
来 自:仙女座大星云
等 级:贵宾
威 望:19
帖 子:3951
专家分:748
注 册:2007-11-16
收藏
得分:0 
恩,最近写旧式代码写习惯了……很多地方旧时代码还是很流行的,比如内核代码,再比如Vim的代码~~~

这个是新式的,C/C++编译通过,再试试吧。你改过的那个代码是错的,因为memory必须是void*,否则memory+size就会出问题。当然你可以把memory的类型改为struct shm_data_st*,但是size的[bo]含义[/bo]必须相应改为memory将装下的结构体的[bo]个数[/bo],而不是内存的实际大小。

程序代码:
#include <stdio.h>
#include <assert.h>

struct shm_data_st
{
    struct shm_data_st *pre;
    char data[10];
    struct shm_data_st *next;
};

struct shm_data_st* init_shm_data(void *memory, size_t size)
{
    struct  shm_data_st *pt = (struct shm_data_st*)memory;
    struct  shm_data_st *end = (struct shm_data_st*)((char*)memory + size);

    assert(memory != NULL && size != 0);

    for (; pt < end; ++pt)
    {
        pt->pre = pt - 1;
        sprintf(pt->data, "struct %d", pt - (struct shm_data_st*)memory);
        pt->next = pt + 1;
    }

    ((struct shm_data_st*)memory)->pre = NULL;
    pt[-1].next = NULL;

    return (struct shm_data_st*)memory;
}

int main(void)
{
    char buf[1000];
    struct shm_data_st *pt;

    init_shm_data(buf, 1000);

    for (pt = (struct shm_data_st*)buf;
            pt != NULL;
            pt = pt->next)
        puts(pt->data);

    return 0;
}

专心编程………
飞燕算法初级群:3996098
我的Blog
2009-07-27 03:10
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
呵呵 明白了,在我获取shm_data_st *end 的时候 差太远了,光考虑了for循环的指针加减,没想到忽略了这没一个严重的问题,看来以后考虑问题要更小心啊。要不是StarWing83你提醒一下,我还真的以为问题解决了,太危险了 。

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-27 09:15
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
如果改成结构体个数的话,确实不如使用size节约内存,使用内存大小可以获得最高的使用率,计算个数的话那就要看算得多精确了

StarWing83你还真是细心啊,什么时候能够考虑得像你一样周全阿,哈哈

[[it] 本帖最后由 asmdaydream 于 2009-7-27 09:25 编辑 [/it]]

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-27 09:18
lin52045
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:41
专家分:113
注 册:2009-7-24
收藏
得分:0 
两位大神

C语言入门新手,大家一起讨论学习!
2009-07-27 10:20
快速回复:请教:我想做一个比较特别的双向列表,指针作加法有点问题,大家帮我看 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025330 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved