| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 459 人关注过本帖
标题:指针,函数调用类问题
只看楼主 加入收藏
放轻松C
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2014-2-25
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:5 
指针,函数调用类问题
一个程序要求是,运用指针去实现两个通分之后的分式之和。
我的程序如下:
int gcd(Fraction *a,Fraction *b)
{
    int *t;
    if(a->s<b->s)
    {
        *t=a->s;
        a->s=b->s;
        b->s=*t;
    }
    while(a->s%b->s!=0)
    {
        *t=a->s%b->s;
        a->s=b->s;
        b->s=*t;
    }
    return b->s;
}

void SuMTFfraction(Fraction a,Fraction b,Fraction *c)
{
    int *e;
    *e=a.s*b.s/gcd(Fraction a,Fraction b);
    c->r=*e/a.s*a.r+*e/b.s*b.r;
    c->s=*e;
}
定义的gcd函数求两个分式分母的最小公约数本人想通过调用gcd函数来实现两个分式的通分,以便于得到通分后的两式之和。
另外fraction是结构体类型。
typedef struct
{
    NumType r;
    NumType s;
}Fraction;
编译出现错误,比如SumTFfraction函数中关于值的问题,gcd函数中太多实参的问题。已经被指针搞得雾里看花了,希望论坛里有人能指点迷津。谢谢,新手发帖。在线等

搜索更多相关主题的帖子: return 
2014-02-25 19:38
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:15 
1.利用辗转相除求出分母的最大公约数,由此来得到一次同分的分母,然后相加。相加后仍然有可能不是最简分数的,例如(3/4 + 3/4 = 6/4 = 3/2)这个 呃 算是个算法的问题。

2.说下被调函数 void SuMTFfraction(Fraction a,Fraction b,Fraction *c)
在这里面:a,b是属于值传递范围,c属于指针传递。他们属于构造体类型  
c应该是最后的要求的结果吧 那么按照lz你的思路 c->s是合并后的分母,应该是a.s * b.s / gcd(Fraction a,Fraction b) 也就是 原两分母的最小公倍数  lz用*e表示了,这里有个大问题:

lz定义 int *e;  也就是说定义一个指向整形的指针e  但是后面没有了。。。
也就是说 e是一个指针了,系统知道它是指向一个整形 但是lz在程序里面并没说它指向哪一个!
那么 e 也就沦落为了野指针 e里面的值是表示的地址,但是具体指向的哪个地址 ---- 不知道,lz没有个给它指定的整形分配内存空间(甚至没有进行初始化来说明指向谁),后果难以预料,非常危险(可能该e不可用导致程序崩溃,或者非法访问到某些关键内存,导致电脑出问题)。
至少应该这样: int x; int *e; e = &x; 这样 e 就能用了。
同样在被调函数:int gcd(Fraction *a,Fraction *b) 里面 也有这样的问题: int *t; t 是野指针。

3.被调函数:int gcd(Fraction *a,Fraction *b) 里面
a b 属于指针传递 在被调函数被调函数 void SuMTFfraction(Fraction a,Fraction b,Fraction *c)里面有这么一个语句:*e=a.s*b.s/gcd(Fraction a,Fraction b); gcd的函数形参应该是指针类型的 也就是说调用的话得用:gcd(&a,&b)的(实参)形式 ---- 首先它得是一个地址 而且是(Fraction *)类型的  不过这里是实参就不用类型说明符了。。不然,这里系统可能会理解为重复定义(Fraction a;的形式是定义一个名字为a的Fraction构造体类型)

如果这个函数调用改了以后,又有一个问题,gcd里面是指针访问,会改变void SuMTFfraction(Fraction a,Fraction b,Fraction *c)这个函数里面 a b的值的,当gcd调用结束,再进行c->r=*e/a.s*a.r+*e/b.s*b.r; 的语句,结果应该不会是你想要的类型了。因为a.s  b.s 值可能已经变的面目全非了。 解决这个问题 嗯 你可以吧gcd改为值传递方式,或者在gcd里面通过中间变量来进行:(如下)
int x; int y; int z; t = &x; y = a -> s; z = b -> s; 然后再用辗转相除 返回一个值...
收到的鲜花
  • 放轻松C2014-02-25 21:52 送鲜花  3朵   附言:好文章

未知令人期待!
2014-02-25 20:27
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:5 
我也写了一个通分并化简的程序   可能和你要求不一样
程序代码:
#include<stdio.h>
#include<stdlib.h>

int gcd(int x,int y) 
//欧几里得辗转相除法求两数的最大的公约数
{
    if(x<y)    return gcd(y,x);
    if(x%y!=0) return gcd(y,x%y);
    else return y;
}

void cal_formul(char* x,char* y,char* z)
{
    int a1,b1,a2,b2,c1,c2,g;
    char buf[20]={'\0'};
    int i=0;
    while(*x!='\0')
    {
        buf[i]=*x;
        if(*x=='/') break;
        i++;
        x++;
    }
    a1=atoi(buf);
    i=0;
    x++;
    while(*x!='\0')
    {
        buf[i]=*x;
        i++;
        x++;
    }
    b1=atoi(buf);
    ////////////////////////////////////
    i=0;
    while(*y!='\0')
    {
        buf[i]=*y;
        if(*y=='/') break;
        i++;
        y++;
    }
    a2=atoi(buf);
    i=0;
    y++;
    while(*y!='\0')
    {
        buf[i]=*y;
        i++;
        y++;
    }
    b2=atoi(buf);
    ////////////////////////////////////////////////
    c1=a1*b2+b1*a2;
    c2=b1*b2;
    g=gcd(c1,c2);
    c1=(a1*b2+b1*a2)/g;
    c2=(b1*b2)/g;
    _itoa(c1,buf,10);
    i=0;
    while(buf[i]!='\0')
    {
        *z=buf[i];
        z++;
        i++;
    }
    *z='/';
    z++;
    _itoa(c2,buf,10);
    i=0;
    while(buf[i]!='\0')
    {
        *z=buf[i];
        z++;
        i++;
    }
}


int main()
{   
    char x[]="406/747";
    char y[]="678/555";
    char z[20]={'\0'};
    cal_formul(x,y,z);
    printf("%s + %s = %s\n",x,y,z);
    return 0;
}




DO IT YOURSELF !
2014-02-25 21:44
放轻松C
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2014-2-25
收藏
得分:0 
回复 2楼 神机军师
不好意思,回复错了。谢谢,分析的很透彻。本人是新手,受益匪浅。以后多练习指针这方面的东西,算法也是第一次接触,十分感谢。

[ 本帖最后由 放轻松C 于 2014-2-25 22:05 编辑 ]
2014-02-25 22:02
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:0 
回复 4楼 放轻松C
我不是版主 楼主你发错人啦

未知令人期待!
2014-02-25 22:04
放轻松C
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2014-2-25
收藏
得分:0 
回复 3楼 wp231957
谢楼主。昨晚发错人了灰常感谢,问题已解决
2014-02-26 11:10
快速回复:指针,函数调用类问题
数据加载中...
 
   



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

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