鱼C论坛

 找回密码
 立即注册
查看: 2594|回复: 22

末知错误

[复制链接]
发表于 2015-4-5 20:30:05 | 显示全部楼层 |阅读模式
30鱼币
本帖最后由 haiouda 于 2015-4-8 23:01 编辑
#include<stdio.h>
#include<malloc.h>
#include<math.h>


#define LEN sizeof(struct Nuu)

struct Nuu         //定义结构体
{
        int digit;
        struct Nuu *next;
};


int main()
{
        int i=0,k=0,n=0,a[20],c[20],*p,*q;   //数组c用来存放每行第一个数字,数组a用来暂存 第一个数以后的数字,且是排好序的。
        void  szpl(int *b,int *q,int k);         //输入和排序
    void print(struct Nuu *head,int *q,int k);  //输出函数
    
        struct Nuu *head,*p1,*p2;          // 定义指向结构的指针
        
        p=a;      //  p指针,指向a
        q=c;      //  q指针,指向c
        
        head=NULL;                        // 结构头为空;
        
        scanf("%d",&a[n]);             //a 接收第一个数字;
        
        
    for(;;)
        {                
                
                if (a[0]==0) break;     // 当第一个数,输入为0 时,退出程序
                
                else
                {                        
                        c[k]=a[0];   // 数组C 用来存 每行第一个数字
                        
                        
                        szpl(p,q,k);        //输入和排序
                        
                        
                        
                        
                        if(head==NULL)               
                        {
                                p1=(struct Nuu *) calloc(c[k],LEN);     // 下面几行是把数组a 内的元素,加入到链表中                            
                                head=p1;
                                for(i=0;i<c[k];i++)
                                {          
                                        p2=p1;
                                        p2->digit=a[i];        
                                        p1=p1+1;                                                                 
                                        p2->next=p1;
                                        
                                }                        
                                p2->next=NULL;
                                
                        }
                        else                                          // 下面几行是把数组a 内的元素,加入到链表中  
                        {
                                p1=(struct Nuu *) calloc(c[k],LEN);   //定义 c[k]个,LEN,返回头指针

                                 p2->next=p1; 
                                  for(i=0;i<c[k];i++)
                                { 
                   
                    p2=p1;
                                        p2->digit=a[i];
                                        p1=p1+1;       //这里我犯了个错误p1是结构的指针,不是普通指针,所以p1+LEN与p1+1不等价
                    p2->next=p1;             
                                                                                                                        
                                }
                                p2->next=NULL;
                        }
                        
                }
                
                
                n=0;        k++;         // n=0; 为重新输入数组a 做准备;k++;准备车入数组c的下一上元素
                
                scanf("%d",&a[n]);
                
        }
        print(head,q,k);     //输出链表
        printf("\n\n");
        
        
        return 0;
}





void  szpl(int *b,int *q,int k)     //输入并安要求排序
{
        int i,m,temp;
        
        for(i=0;i<*(q+k);i++)
        {                
                scanf("%d",&b[i]);        
        }
        
        
        
        for(i=0;i<*(q+k);i++)
        {
                for(m=i+1;m<*(q+k);m++)
                {
                        if( abs(*(b+i)) < abs(*(b+m)))
                        {
                                temp=*(b+i);
                                *(b+i)=*(b+m);
                                *(b+m)=temp;
                                
                        }
                        
                }
        }
        
        
}




void print(struct Nuu *head,int *q,int k)     //输出
{
        int i,m;
        struct Nuu *p;
        p=head;
        
        for(i=0;i<k;i++)
        {
                for(m=0; m<*(q+i);m++)
                {
                        printf("%d ",p->digit);
                        p=p->next;                        
                }
                printf("\n");
                
        }
            
}
用calloc一次建立的相邻的二个结点指针差,为何不是一个定值?
我是菜鸟,写程序的格式,难免不入流,希望各位大神们凉解。本次补上比较详细的注解方便各位阅读,希望不吝赐教 :handshake

8888888888888.png
1111111111111111.jpg

最佳答案

查看完整内容

首先,你的代码好难看,不易懂,看的我都没心情往下看了;不知道是不是要求用指针的,对于这道题,我觉得你有点滥用指针了。 其实错的地方只有一个(两处)54行和71行的 p1=p1+LEN; 该为p1=p1+1; 指针加上或减去一个数n,不是指针所指向的地址加上或减去n个字节,而是加上或减去n的该指针类型的对象。 这样说你应该明白了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-8 22:19:46 | 显示全部楼层

二个next 之间的长度,应该就是结构的长度,可二个next 之间的长度一直在循环!?这是为什么?
8888888888888.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-5 20:30:06 | 显示全部楼层
首先,你的代码好难看,不易懂,看的我都没心情往下看了;不知道是不是要求用指针的,对于这道题,我觉得你有点滥用指针了。
其实错的地方只有一个(两处)54行和71行的  p1=p1+LEN;
该为p1=p1+1;
指针加上或减去一个数n,不是指针所指向的地址加上或减去n个字节,而是加上或减去n的该指针类型的对象。
这样说你应该明白了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-6 23:26:46 | 显示全部楼层
本帖最后由 haiouda 于 2015-4-6 23:57 编辑

新建结点,地址为零,有木有人知道为什么呀:sad
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-7 11:20:45 | 显示全部楼层
本帖最后由 haiouda 于 2015-4-7 11:56 编辑
j_t_zeng 发表于 2015-4-7 03:07
首先,你的代码好难看,不易懂,看的我都没心情往下看了;不知道是不是要求用指针的,对于这道题,我觉得你 ...

我刚开始学习C语言,写代码还没有养成固定的习惯,以后慢慢会好滴;我把程序做了详细注释,相信这样读起来方便多了
其次这题目,是网友出的,我初学结构,就用结构的方法套了上去,肯定不是最简单的方法了。

p1指针,指向结构体,p1+1,指向下一个结点;  (事实上,p1+1  和p1+LEN(结构体长度) ;在理论上是相等的。)
上面的, 是我一开始的做法,可实际与所想的有些出入。

具体是:假如p1的地址是 0xaa2510; 通过跟踪发现p1+1的地址是0xaa2512,它们只差二个字节;

事实上,54行可正常运行,71行第一次循环时也可以正常运行,问题出在71行第二次循环时;
还有动态链表定义结点时,我用malloc 定义结点时,是没有出错的;手欠,改用calloc 定义结点才出错的,最让我头痛的是,我找不到出错的原因(新结点返回的指针,直接指向 0 ,这是我遇到最多出错形式;还有一种出错的形式是,当输入为负数时, 在应该输出负数的位置出现一个末知的数字,其它输出正常)。

最后,感谢热心回复:handshake


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-7 11:25:47 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-7 13:13:21 | 显示全部楼层
本帖最后由 j_t_zeng 于 2015-4-7 13:15 编辑
haiouda 发表于 2015-4-7 11:20
我刚开始学习C语言,写代码还没有养成固定的习惯,以后慢慢会好滴;我把程序做了详细注释,相信这样读起 ...

楼主,你错了,p1+1  和p1+LEN(结构体长度) 是不一样的,当然除非LEN==1,。你可以测试下,或者把你的代码按我说的改一下试试,我是在Linux下测试的,关于指针的结论和我说的一样。题目按图例也没问题(没测试其他的情况)。如果不行,能否把你出错的信息也给截图了。我是大一时学的c,现在也忘了基本了,有问题咱们可以探讨一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-8 08:21:31 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-8 08:43:42 | 显示全部楼层
本帖最后由 haiouda 于 2015-4-8 08:45 编辑
j_t_zeng 发表于 2015-4-7 13:13
楼主,你错了,p1+1  和p1+LEN(结构体长度) 是不一样的,当然除非LEN==1,。你可以测试下,或者把你的代码 ...

楼上有图 p1是指向结构体的指针
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-8 21:48:48 | 显示全部楼层
本帖最后由 haiouda 于 2015-4-8 21:53 编辑

看来这问题,只有后面学32个汇编时,才能弄明白了:mad:

p1 和 p1+1 的地址,只差了二个字节;
而结构长度确为8个字节。 p1+1 为何能指向下一个结点???
33333333.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-8 22:45:29 | 显示全部楼层
j_t_zeng 发表于 2015-4-7 13:13
楼主,你错了,p1+1  和p1+LEN(结构体长度) 是不一样的,当然除非LEN==1,。你可以测试下,或者把你的代码 ...

你说得有道理,现在对上面的程序我发现了,新的问题,就是改成p1+1,后,跟踪p1的地址(跟踪next的地址),二个(next)之间的地址,应该是相等的,且等于结构的长度(8),而跟踪后发现,二个next 地址差不不是一个定值,而是一会2一会8,这样循环下去,而程序还能正确运行,这里就搞不懂了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-9 12:24:13 | 显示全部楼层
haiouda 发表于 2015-4-8 22:45
你说得有道理,现在对上面的程序我发现了,新的问题,就是改成p1+1,后,跟踪p1的地址(跟踪next的地址) ...

楼主,你看错了,地址差一直 是8个字节。注意 0x00540f28和0x00540f30都是十六进制的数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:09:20 | 显示全部楼层
j_t_zeng 发表于 2015-4-9 12:24
楼主,你看错了,地址差一直 是8个字节。注意 0x00540f28和0x00540f30都是十六进制的数

不会的;
16进制的8 和10进制里的8如果出现在个位(最低位)是没有区别的;

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-9 13:18:35 | 显示全部楼层
haiouda 发表于 2015-4-9 13:09
不会的;
16进制的8 和10进制里的8如果出现在个位(最低位)是没有区别的;

这样说的,十六进制,0x30和0x28想差多少,你应该知道吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:20:13 | 显示全部楼层
j_t_zeng 发表于 2015-4-9 13:18
这样说的,十六进制,0x30和0x28想差多少,你应该知道吧
晕,我错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:23:30 | 显示全部楼层
本帖最后由 haiouda 于 2015-4-9 13:28 编辑
j_t_zeng 发表于 2015-4-9 13:18
这样说的,十六进制,0x30和0x28想差多少,你应该知道吧

可是即便这样,也没法解释最上面(我更新了的问题)。

上面定义的结构长度是 8 个字节,可你看上面我新发的图; 新结点的地址和头地址差(或者观察:二个结点的地址差值)不是结构体长度8,而是在有规律地变化……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-9 13:35:17 | 显示全部楼层
haiouda 发表于 2015-4-9 13:23
可是即便这样,也没法解释最上面(我更新了的问题)。

上面定义的结构长度是 8 个字节,可你看上面我 ...

不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:41:15 | 显示全部楼层
j_t_zeng 发表于 2015-4-9 13:35
不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊

上在我用 calloc()函数,定义了连续的,几个新结点;
由上面结构体长度为8个字节,所以上面定义的新结点之间的地址差应该是8个了节;

见最上面我更新了的图,观察几人新结点之间的地址之差值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:45:05 | 显示全部楼层
j_t_zeng 发表于 2015-4-9 13:35
不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊

看来我又错了,十分感谢你的回答:handshake
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-4-9 13:45:27 | 显示全部楼层
haiouda 发表于 2015-4-9 13:41
上在我用 calloc()函数,定义了连续的,几个新结点;
由上面结构体长度为8个字节,所以上面定义的新结点 ...

head指向地址0x28,他的下个节点地址是0x30,相差8;
地址为0x30的节点,他的下个节点地址是0x38,相差8;
地址为0x38的节点,他的下个节点地址是0x40,相差8;
……
每个相邻的节点相差都是8啊,难道不是这个疑惑
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-26 00:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表