鱼C论坛

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

末知错误

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


  4. #define LEN sizeof(struct Nuu)

  5. struct Nuu         //定义结构体
  6. {
  7.         int digit;
  8.         struct Nuu *next;
  9. };


  10. int main()
  11. {
  12.         int i=0,k=0,n=0,a[20],c[20],*p,*q;   //数组c用来存放每行第一个数字,数组a用来暂存 第一个数以后的数字,且是排好序的。
  13.         void  szpl(int *b,int *q,int k);         //输入和排序
  14.     void print(struct Nuu *head,int *q,int k);  //输出函数
  15.    
  16.         struct Nuu *head,*p1,*p2;          // 定义指向结构的指针
  17.         
  18.         p=a;      //  p指针,指向a
  19.         q=c;      //  q指针,指向c
  20.         
  21.         head=NULL;                        // 结构头为空;
  22.         
  23.         scanf("%d",&a[n]);             //a 接收第一个数字;
  24.         
  25.         
  26.     for(;;)
  27.         {               
  28.                
  29.                 if (a[0]==0) break;     // 当第一个数,输入为0 时,退出程序
  30.                
  31.                 else
  32.                 {                        
  33.                         c[k]=a[0];   // 数组C 用来存 每行第一个数字
  34.                         
  35.                         
  36.                         szpl(p,q,k);        //输入和排序
  37.                         
  38.                         
  39.                         
  40.                         
  41.                         if(head==NULL)               
  42.                         {
  43.                                 p1=(struct Nuu *) calloc(c[k],LEN);     // 下面几行是把数组a 内的元素,加入到链表中                           
  44.                                 head=p1;
  45.                                 for(i=0;i<c[k];i++)
  46.                                 {         
  47.                                         p2=p1;
  48.                                         p2->digit=a[i];        
  49.                                         p1=p1+1;                                                                 
  50.                                         p2->next=p1;
  51.                                        
  52.                                 }                        
  53.                                 p2->next=NULL;
  54.                                 
  55.                         }
  56.                         else                                          // 下面几行是把数组a 内的元素,加入到链表中  
  57.                         {
  58.                                 p1=(struct Nuu *) calloc(c[k],LEN);   //定义 c[k]个,LEN,返回头指针

  59.                                  p2->next=p1;
  60.                                   for(i=0;i<c[k];i++)
  61.                                 {
  62.                   
  63.                     p2=p1;
  64.                                         p2->digit=a[i];
  65.                                         p1=p1+1;       //这里我犯了个错误p1是结构的指针,不是普通指针,所以p1+LEN与p1+1不等价
  66.                     p2->next=p1;            
  67.                                                                                                                         
  68.                                 }
  69.                                 p2->next=NULL;
  70.                         }
  71.                         
  72.                 }
  73.                
  74.                
  75.                 n=0;        k++;         // n=0; 为重新输入数组a 做准备;k++;准备车入数组c的下一上元素
  76.                
  77.                 scanf("%d",&a[n]);
  78.                
  79.         }
  80.         print(head,q,k);     //输出链表
  81.         printf("\n\n");
  82.         
  83.         
  84.         return 0;
  85. }





  86. void  szpl(int *b,int *q,int k)     //输入并安要求排序
  87. {
  88.         int i,m,temp;
  89.         
  90.         for(i=0;i<*(q+k);i++)
  91.         {               
  92.                 scanf("%d",&b[i]);        
  93.         }
  94.         
  95.         
  96.         
  97.         for(i=0;i<*(q+k);i++)
  98.         {
  99.                 for(m=i+1;m<*(q+k);m++)
  100.                 {
  101.                         if( abs(*(b+i)) < abs(*(b+m)))
  102.                         {
  103.                                 temp=*(b+i);
  104.                                 *(b+i)=*(b+m);
  105.                                 *(b+m)=temp;
  106.                                 
  107.                         }
  108.                         
  109.                 }
  110.         }
  111.         
  112.         
  113. }




  114. void print(struct Nuu *head,int *q,int k)     //输出
  115. {
  116.         int i,m;
  117.         struct Nuu *p;
  118.         p=head;
  119.         
  120.         for(i=0;i<k;i++)
  121.         {
  122.                 for(m=0; m<*(q+i);m++)
  123.                 {
  124.                         printf("%d ",p->digit);
  125.                         p=p->next;                        
  126.                 }
  127.                 printf("\n");
  128.                
  129.         }
  130.             
  131. }











复制代码
用calloc一次建立的相邻的二个结点指针差,为何不是一个定值?
我是菜鸟,写程序的格式,难免不入流,希望各位大神们凉解。本次补上比较详细的注解方便各位阅读,希望不吝赐教 :handshake

8888888888888.png
1111111111111111.jpg

最佳答案

查看完整内容

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

使用道具 举报

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

二个next 之间的长度,应该就是结构的长度,可二个next 之间的长度一直在循环!?这是为什么?
8888888888888.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

新建结点,地址为零,有木有人知道为什么呀:sad
小甲鱼最新课程 -> https://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


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-4-7 11:25:47 | 显示全部楼层
{:1_1:}
小甲鱼最新课程 -> https://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,现在也忘了基本了,有问题咱们可以探讨一下
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2015-4-8 08:21:31 | 显示全部楼层
{:1_1:}
小甲鱼最新课程 -> https://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是指向结构体的指针
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

p1 和 p1+1 的地址,只差了二个字节;
而结构长度确为8个字节。 p1+1 为何能指向下一个结点???
33333333.jpg
小甲鱼最新课程 -> https://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,这样循环下去,而程序还能正确运行,这里就搞不懂了。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

楼主,你看错了,地址差一直 是8个字节。注意 0x00540f28和0x00540f30都是十六进制的数
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

这样说的,十六进制,0x30和0x28想差多少,你应该知道吧
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-4-9 13:20:13 | 显示全部楼层
j_t_zeng 发表于 2015-4-9 13:18
这样说的,十六进制,0x30和0x28想差多少,你应该知道吧
晕,我错了
小甲鱼最新课程 -> https://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,而是在有规律地变化……
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

不知是我没理解你说的吗?
每个节点的地址和相邻的节点地址是8个字节啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

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

见最上面我更新了的图,观察几人新结点之间的地址之差值。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

看来我又错了,十分感谢你的回答:handshake
小甲鱼最新课程 -> https://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啊,难道不是这个疑惑
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-19 15:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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