haiouda 发表于 2015-4-5 20:30:05

末知错误

本帖最后由 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,c,*p,*q;   //数组c用来存放每行第一个数字,数组a用来暂存 第一个数以后的数字,且是排好序的。
      voidszpl(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);             //a 接收第一个数字;
      
      
    for(;;)
      {               
               
                if (a==0) break;   // 当第一个数,输入为0 时,退出程序
               
                else
                {                        
                        c=a;   // 数组C 用来存 每行第一个数字
                        
                        
                        szpl(p,q,k);      //输入和排序
                        
                        
                        
                        
                        if(head==NULL)               
                        {
                              p1=(struct Nuu *) calloc(c,LEN);   // 下面几行是把数组a 内的元素,加入到链表中                           
                              head=p1;
                              for(i=0;i<c;i++)
                              {         
                                        p2=p1;
                                        p2->digit=a;      
                                        p1=p1+1;                                                               
                                        p2->next=p1;
                                       
                              }                        
                              p2->next=NULL;
                              
                        }
                        else                                          // 下面几行是把数组a 内的元素,加入到链表中
                        {
                              p1=(struct Nuu *) calloc(c,LEN);   //定义 c个,LEN,返回头指针

                                 p2->next=p1;
                                  for(i=0;i<c;i++)
                              {
                  
                  p2=p1;
                                        p2->digit=a;
                                        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);
               
      }
      print(head,q,k);   //输出链表
      printf("\n\n");
      
      
      return 0;
}





voidszpl(int *b,int *q,int k)   //输入并安要求排序
{
      int i,m,temp;
      
      for(i=0;i<*(q+k);i++)
      {               
                scanf("%d",&b);      
      }
      
      
      
      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

haiouda 发表于 2015-4-8 22:19:46


二个next 之间的长度,应该就是结构的长度,可二个next 之间的长度一直在循环!?这是为什么?

j_t_zeng 发表于 2015-4-5 20:30:06

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

haiouda 发表于 2015-4-6 23:26:46

本帖最后由 haiouda 于 2015-4-6 23:57 编辑

新建结点,地址为零,有木有人知道为什么呀:sad

haiouda 发表于 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


364904690 发表于 2015-4-7 11:25:47

{:1_1:}

j_t_zeng 发表于 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,现在也忘了基本了,有问题咱们可以探讨一下

taochen 发表于 2015-4-8 08:21:31

{:1_1:}

haiouda 发表于 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是指向结构体的指针

haiouda 发表于 2015-4-8 21:48:48

本帖最后由 haiouda 于 2015-4-8 21:53 编辑

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

p1 和 p1+1 的地址,只差了二个字节;
而结构长度确为8个字节。 p1+1 为何能指向下一个结点???

haiouda 发表于 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,这样循环下去,而程序还能正确运行,这里就搞不懂了。

j_t_zeng 发表于 2015-4-9 12:24:13

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

楼主,你看错了,地址差一直 是8个字节。注意 0x00540f28和0x00540f30都是十六进制的数

haiouda 发表于 2015-4-9 13:09:20

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

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

j_t_zeng 发表于 2015-4-9 13:18:35

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

这样说的,十六进制,0x30和0x28想差多少,你应该知道吧

haiouda 发表于 2015-4-9 13:20:13

j_t_zeng 发表于 2015-4-9 13:18
这样说的,十六进制,0x30和0x28想差多少,你应该知道吧晕,我错了

haiouda 发表于 2015-4-9 13:23:30

本帖最后由 haiouda 于 2015-4-9 13:28 编辑

j_t_zeng 发表于 2015-4-9 13:18
这样说的,十六进制,0x30和0x28想差多少,你应该知道吧
可是即便这样,也没法解释最上面(我更新了的问题)。

上面定义的结构长度是 8 个字节,可你看上面我新发的图; 新结点的地址和头地址差(或者观察:二个结点的地址差值)不是结构体长度8,而是在有规律地变化……

j_t_zeng 发表于 2015-4-9 13:35:17

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

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

不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊

haiouda 发表于 2015-4-9 13:41:15

j_t_zeng 发表于 2015-4-9 13:35
不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊

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

见最上面我更新了的图,观察几人新结点之间的地址之差值。

haiouda 发表于 2015-4-9 13:45:05

j_t_zeng 发表于 2015-4-9 13:35
不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊

看来我又错了,十分感谢你的回答:handshake

j_t_zeng 发表于 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啊,难道不是这个疑惑
页: [1] 2
查看完整版本: 末知错误