免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4312 | 回复: 15
打印 上一主题 下一主题

[C] 刚学完c。求教,自写一小程序不知道错哪里。一直遵循努力自己解决问题的原则。但。。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-16 23:19 |只看该作者 |倒序浏览
#include<stdio.h>
                                                                  //我的目的是输入i个学生成绩(每个学生4门成绩);然后一个一个的输出各学生的平均
void average(float *p,int x,int y);        // 成绩,然后输出所有学生的所有成绩。
void search(float (*p)[4],int x,int y);   //(×p)是指向一维数组的指针变量                       

int main()
{       
        int j=0;
        int i=0;
        int student=0;
        float score[i][4];
        float (*p)[4]=NULL;

        printf("请输入学生人数:\n");
        scanf("%d",&student);

        printf("你输入的学生人数是:%d\n",student);
       
        printf("请输入学生成绩:\n");
       
        p=score;
        for(i=0;i<student;i++)
                for(j=0;j<4;j++)
                           scanf("%f",*(p+i)+j);                   //&(*(*(p+i)+j)))
       
        average(*p,student,4);
        search(p,student,4);

        return 0;
       
}
       
void average(float *p,int x,int y)
{
        float aver=0;
        int i=0;
        int j=0;
        float sum=0;

        for(i=0;i<x;i++)
          {     
                sum=0;
                 for(j=0;j<y;j++)
                  {
                        sum=sum+*p;
                  }
                aver=sum/y;
                printf("\n第%d个同学的平均成绩为:%5.2f\n",i,aver);
          }
}


void search(float (*p)[4],int x,int y)
{
        int i=0;
        int j=0;
        float fenshu=0;
       
        for(i=0;i<x;i++)
          {       
                printf("\n第%d个同学各科成绩:\n",i);
                for(j=0;j<y;j++)
                  {
                           fenshu=*(*(p+i)+j);
                        printf("%5.2f",fenshu);       
                  }
          }       
       
}

论坛徽章:
1
处女座
日期:2014-09-18 16:18:00
2 [报告]
发表于 2013-12-17 09:01 |只看该作者
回复 1# 。风中劲草。
没仔细看你的代码,不知道你具体有什么问题,但是很明显有一点错误,我看你申请数组的时候score[4],我想你的意图应该是根据学生的总数来动态申请数组大小吧,4应该是一个学生有4门成绩?
那你这样做是不对的,因为你的i初始化为0,那么你可以理解为实际上申请的数组大小就是一个1行4列的矩阵,假设你的学生总数>1,那么你从*p地址开始填写内存的时候,就会溢出,也就时你填写了你并没有申请的地址空间,这是严重错误的。一般动态申请数组使用malloc函数,你可以去查一下。

   

论坛徽章:
0
3 [报告]
发表于 2013-12-17 11:05 |只看该作者
float score[i][4];  // 声明数组长度不能用变量

void search(float (*p)[4],int x,int y);   //(×p)是指向一维数组的指针变量
通常用2级指针 float **p

看编译器的提示改

论坛徽章:
0
4 [报告]
发表于 2013-12-17 11:19 |只看该作者
本帖最后由 dxyf1524 于 2013-12-17 11:23 编辑

        float score[4];
        float (*p)[4]=NULL;
你换个方法做个吧,不知道你的编译怎么通过的,
用指针数组比较复杂,考虑简单的方法吧
实在不行,用结构体

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
5 [报告]
发表于 2013-12-17 11:42 |只看该作者
To 3楼、4楼:怎么通过的?当然是用gcc啊,不然这么神奇的语法。。。
To 2楼:float score[0][4];  声明的是0行4列的数组,也就是没分配任何空间。

To 楼主:
过去,C语言中是没法声明一个变量长度的数组的。后来在C99标准中添加了这个特性,而gcc默认情况下(不是用-std=c99)就支持这个特性。当然,长度为0的数组也是一个gcc的扩展。下面两个链接作为参考:

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html


需要注意的是,虽然你可以声明一个变量长度的数组,但是这个数组的长度不会随着这个变量的变化而变化,而是在声明之后就固定下来了。所以,下面的语句:
  1.          int j=0;
  2.         int i=0;
  3.         int student=0;
  4.         float score[i][4];
复制代码
score是个长度为0的数组,它实际上不占任何空间,所以向里面存东西是错误的,会溢出。

正确的做法:
1. 取得学生人数后再声明score,不是一个好方法。
2. 学习使用malloc/free函数,自己分配内存。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2013-12-17 14:26 |只看该作者
还有:

你定义P为指针:float (*p)[4]=NULL;
然后你这里用:scanf("%f",*(p+i)+j);
你想想p为地址,*(p+i)之后还是地址吗?不是地址你还可以用来放在scanf中做参数吗?

论坛徽章:
1
处女座
日期:2014-09-18 16:18:00
7 [报告]
发表于 2013-12-17 14:33 |只看该作者
回复 5# zhaohongjian000
额,大早起来脑袋有点晕,索引开始和数组长度居然弄晕了,你说的是对的,其实没有分配任何空间。
这个地址确实是可以用的,但是写到哪里就不得而知了,会损坏什么关键数据也不得而知了。
to楼上,*(p+i)当然是地址,因为这里p本身是一个二级指针,但是是一个没有被内核分配给该进程的地址,换句话说就是在操作一个非法空间,gcc编译也是可以通过的,甚至得到结果都有可能正确,但是做法显然是错误的

   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2013-12-17 15:05 |只看该作者
回复 7# Kasiotao


    不听我的话,你还是自己写个程序试一下吧,你这里定义p就是一级指针。不想解释了。

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
9 [报告]
发表于 2013-12-17 15:19 |只看该作者
回复 8# ntwarren


    我觉得你才需要写个程序试一下。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2013-12-17 15:36 |只看该作者
回复 9# zhaohongjian000

#include <stdio.h>
#include <stdlib.h>

int main(){
    int a[8][10] = {4};
    int (*p)[4];
    p = a;
   

    printf("%d\n",*((int*)p));
    printf("%d\n",a[0][0]);

}



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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP