none
函数返回值无法输出 RRS feed

  • 问题

  • 自定义的函数的返回值在返回之前是“正常的”,但是在返回之后就“不正常”了。大家帮我看看是怎么回事

    下面是源码:

    #include<stdio.h>
    #include<stdlib.h>
    #include<limits.h>
    #include<float.h>
    #include<math.h>
    #include<locale.h>
    
    char * dtostr(double);
    
    int main(void)
    {
    	double a;
    	char *result;
    	//scanf("%lf",&a); //替补输入
    	_scanf_l("%lf",LC_ALL,&a);
    	result = dtostr(a);
    	printf("input value = %s\n",result); //输出失败
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    //char dblstr[sizeof(LDBL_MAX)+20]={NULL},itpt[sizeof(LDBL_MAX)+1]={NULL},dept[sizeof(LDBL_MAX)+10]={NULL}; //变量为全局变量程序输出正常;变量为局部变量程序输出异常
    
    char * dtostr(double x) //完成数值转换为字符串
    {
    	double power(int,int); //自己写的幂函数,没有用math头文件里面的
    	char dblstr[sizeof(LDBL_MAX)+20]={NULL};//结果存储单元
    	char itpt[sizeof(LDBL_MAX)+1]={NULL};//整数存储单元
    	char dept[sizeof(LDBL_MAX)+10]={NULL}; //小数存储单元
    	int i,j,k;
    	int intpt,decpt; //intpt是整数部分integer;decpt是小数部分decimal number
    	char *result; //结果指针
    
    	/*判断数值的正负号以及申请小数部分的存储单元*/
    	i = 0;
    	if (x>0)
    	{
    		intpt = (int)x;
    		dblstr[i++] = ' ';
    		decpt = (int)((x - (int)x)*(int)power(10,sizeof(ULONG_MAX)+2));
    	}
    	else
    	{
    		intpt = (int)x;
    		dblstr[i++] = '-';
    		x = -x;
    		decpt = (int)((x - (int)x)*(int)power(10,sizeof(ULONG_MAX)+2));
    	}
    
    	/*转换整数部分为字符串*/
    	j = 0;
    	while (abs(intpt)>=1)
    	{
    		itpt[j++] = (char)((int)abs(intpt)%10+48);
    		intpt /= 10;
    	}
    	k = 0;
    	/*转换小数部分为字符串*/
    	while (decpt>=1)
    	{
    		dept[k++] = (char)((int)decpt%10+48);
    		decpt /= 10;
    	}
    	/*整理整数、小数部分字符放置到结果存储单元*/
    	while (k!=0)
    	{
    		if (j>0)
    		{
    			dblstr[i++] = itpt[--j];
    			if (j==0)
    				dblstr[i++] = '.';
    		}
    		if (j==0 && k!=0)
    			dblstr[i++] = dept[--k];
    	}
    
    	/*输出结果*/
    	result = dblstr;
    	printf("output integer value:"); //输出失败
    	for (i=0;i<sizeof(result);i++)
    		printf("%c",*(result+i));
    	printf("\n");
    	printf("output integer value:"); //输出成功
    	for (i=0;i<sizeof(itpt)+sizeof(dept);i++)
    		printf("%c",*(result+i));
    	printf("\n");
    	printf("input value = %s\n",result); //输出成功
    	return result;
    }
    double power(int x,int y)
    {
    	double result=1;
    	int i;
    	for (i=0;i<y;i++)
    		result *= x;
    	return result;
    }

    /*输出结果*/之后貌似就有了问题,但是我就是想不明白,请大家给我说说!

    举例输入:-12.3456

    输出结果:

    -12.3456
    output integer value:-12. 
    output integer value:-12.345599
    input value = -12.345599
    input value = 
    Press any key to continue . . .


    煮酒论英雄

    2012年3月12日 5:48

答案

  • DblToStr函数中返回的指针指向的是局部数组的首地址,局部变量存在栈中,出了函数作用域,局部变量就不在有效,即指针指向的值就不再保证有效,系统可能并不会及时清理该栈上的这些数据,但是可能系统会在特定的时候去清理它。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年3月13日 1:59
    版主
  • 两个实例源码有一个成功一个失败,局部变量申请内存方面和返回值类型方面是一致的。所以我想并不是版主你说的那个作用域问题在作怪。上网查阅相关资料发现还有一个可能就是函数返回值存放在哪里的问题。 引用原文:“这要看具体编译器的设计。对于简单的而且小的返回值,一般放在寄存器,对于复杂的对象作为返回值的时候,一般通过函数调用栈找到返回值的地址,然后写该地址.记得thinking in c++ volume 1中说得很清楚的” 出处:http://www.360doc.com/content/06/0725/17/9577_164241.shtml 在此虽然版主回答并非我所找的答案但是对于每次有问题版主都热情给予解释也是由衷感激。谢谢版主!

    煮酒论英雄

    2012年3月14日 14:18

全部回复

  • 我使用的编译器是vs2010旗舰


    煮酒论英雄

    2012年3月12日 5:55
  • char dblstr[sizeof(LDBL_MAX)+20]={NULL};//结果存储单元
    -->
    static char dblstr[sizeof(LDBL_MAX)+20]={NULL};//结果存储单元

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年3月12日 10:48
    版主
  • char dblstr[sizeof(LDBL_MAX)+20]={NULL};//结果存储单元
    -->
    static char dblstr[sizeof(LDBL_MAX)+20]={NULL};//结果存储单元

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.


    定义全局变量我知道,但是我想知道为什么定义局部变量不行?

    煮酒论英雄

    2012年3月12日 12:53
  • 同样的函数我进行了重写,方法和原理几乎一样,定义的也是局部变量为什么这样就可以正常输出结果了呢?

    源码如下:

    #include<stdio.h>
    #include<stdlib.h>
    #include<locale.h>
    #include<math.h>
    
    #define MAXLINE 1000
    #define PR 8
    
    int main(void)
    {
    	/*声明自定义函数:数值类型转换为字符类型*/
    	char *DblToStr(double,int);
    
    	/*申请变量存储单元*/
    	double x;
    	int n;
    	char *result=NULL;
    
    	/*输入部分*/
    	printf("input double number value:");
    	_scanf_l("%lf",LC_ALL,&x); //输入对象
    	printf("input precision value:");
    	_scanf_l("%d",LC_ALL,&n); //输入要求精度
    
    	/*处理部分*/
    	result = DblToStr(x,n); 
    
    	/*输出部分*/
    	printf("double number converts to string result:%s\n",result); //输出
    
    	system("pause"); //暂停
    
    	return EXIT_SUCCESS;
    }
    char *DblToStr(double x,int n)
    {
    	/*自定义函数:求指数幂*/
    	double power(int,int);
    
    	char dts[MAXLINE]={NULL}; //result partition:处理结果字符数组
    	char intpt[MAXLINE]={NULL}; //integer partition:整数部分字符数组
    	char decpt[MAXLINE]={NULL}; //decimal partition:小数部分字符数组
    	char *result=NULL; //处理结果字符数组指针
    	int i,j,k,count,n1,n2,t,k1,node1; //临时变量
    	double intx,decx1,decx2; //临时变量
    
    	/*判断数值符号*/
    	intx = decx1 = x;
    	i = 0;
    	if (x>0)
    	{
    		dts[i++] = '+';
    	}
    	else
    	{
    		dts[i++] = '-';
    	}
    	/*整数部分转字符*/
    	j = 0;
    	while (abs(intx)>=1)
    	{
    		intpt[j++] = (char)((int)abs(intx)%10+48);
    		intx /= 10;
    	}
    	/*小数部分转字符*/
    	k = 0;
    	n1 = n;
    	while (n>0)
    	{
    		if (n>0)
    		{
    			//printf("decx1=%.18lf\n",decx1); //测试语句
    			decx1 -= (int)decx1;
    			//printf("decx1=%.18lf\n",decx1); //测试语句
    			decx1 *= ((int)power(10,PR));
    			//printf("decx1=%.18lf\n",decx1); //测试语句
    			decx2 = decx1;
    			for (count=0;count<PR;count++)
    			{
    				decpt[k++] = (char)((int)abs(decx2)%10+48);
    				//printf("abs(decx2)=%lf\n",abs(decx2)); //测试语句
    				//printf("((int)abs(decx2))%%10=%d\n",((int)abs(decx2))%10); //测试语句
    				decx2 /= 10;
    			}
    			//printf("decx1=%.18lf\n",decx1); //测试语句
    			n -= PR;
    		}
    	}
    	/*结果字符赋值部分*/
    	while (j>0)
    	{
    		if (j>0)
    		{
    			dts[i++] = intpt[--j];
    			if (j==0)
    				dts[i++] = '.';
    		}
    	}
    	node1 = i;
    	n2 = (n1%PR==0) ? n1/PR : n1/PR+1;
    	for (t=n2-1;t>=0;t--)
    	{
    		count = 0;
    		while (count<PR)
    		{
    			k1 = k-1-count-PR*t;
    			//printf("decpt[%d]=%c\n",k1,decpt[k1]); //测试语句
    			dts[i++] = decpt[k1];
    			count++;
    		}
    	}
    	dts[node1+n1] = '\0';
    	result = dts;
    	return result;
    }
    double power(int x,int y)
    {
    	double result=1;
    	int i;
    	for (i=0;i<y;i++)
    		result *= x;
    	return result;
    }
    输入输出结果如下:
    input double number value:-234.4587732235865
    input precision value:8
    double number converts to string result:-234.45877322
    Press any key to continue . . .

    煮酒论英雄

    2012年3月12日 12:56
  • DblToStr函数中返回的指针指向的是局部数组的首地址,局部变量存在栈中,出了函数作用域,局部变量就不在有效,即指针指向的值就不再保证有效,系统可能并不会及时清理该栈上的这些数据,但是可能系统会在特定的时候去清理它。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年3月13日 1:59
    版主
  • 两个实例源码有一个成功一个失败,局部变量申请内存方面和返回值类型方面是一致的。所以我想并不是版主你说的那个作用域问题在作怪。上网查阅相关资料发现还有一个可能就是函数返回值存放在哪里的问题。 引用原文:“这要看具体编译器的设计。对于简单的而且小的返回值,一般放在寄存器,对于复杂的对象作为返回值的时候,一般通过函数调用栈找到返回值的地址,然后写该地址.记得thinking in c++ volume 1中说得很清楚的” 出处:http://www.360doc.com/content/06/0725/17/9577_164241.shtml 在此虽然版主回答并非我所找的答案但是对于每次有问题版主都热情给予解释也是由衷感激。谢谢版主!

    煮酒论英雄

    2012年3月14日 14:18