回 帖 发 新 帖 刷新版面

主题:[讨论][求助]又是float的问题

下面这段代码在_TYPE为2的时候会运行错误,也就说在max函数中,如果type是float的时候,指针p是不能正确的访问到传递给max的参数。

[code=c]
#define _TYPE 2

#if   _TYPE==1 /******int*****/ 
    #define TYPE int 
#elif _TYPE==2 /*****float****/
    #define TYPE float 
#elif _TYPE==3 /****double****/
    #define TYPE double 
#endif
TYPE LAST_ARG=(TYPE)-1; /****最后一个参数****/

//#include "stdlib.h"
#include "stdio.h"

#define my_assert(x) if(!(x)) do{                    \
            printf("L #%03d 断言失败\n\n",__LINE__); \
            system("pause");exit(1);                 \
            } while(0) 

TYPE max( TYPE a,... )
     {
     TYPE *p     =(TYPE*)(&a) ;      
     TYPE result =  a ;
     while( *++p != LAST_ARG )
            *p>result  ?  result= *p  :  0 ;
     return result ;          
     } // max

int main( void )
    {
    #if (_TYPE==2) || (_TYPE==3)
       TYPE a0=0.0, a1=1.0, a2=2.0, a3=3.0, a4=4.0, 
            a5=5.0, a6=6.0, a7=6.5, a8=8.5, a9=100.0 ;
    #endif

    #if  (_TYPE==1) || (_TYPE==0)
       my_assert( max(1,LAST_ARG)==1 ); 
       my_assert( max(2,5,1,LAST_ARG)==5 );
       my_assert( max(8,4,0,100,LAST_ARG)==100 );
    #elif (_TYPE==2) || (_TYPE==3) 
       my_assert( max(a2,LAST_ARG)==a2 ); 
       my_assert( max(a3,a7,a6,LAST_ARG)==a7 );
       my_assert( max(a0,a4,a1,a9,LAST_ARG)==a9 );
    #endif
  
    printf( " 测试成功!!!\n\n");
    system( "pause" );
    return 0 ;
    }[/code]

回复列表 (共14个回复)

沙发

float类型时,max()发生段错误,指针p访问非法
double和float都以相同机制存储。
既然对float特殊处理,那么不也应该对double也该特殊处理嘛。。

反汇编忘怎么搞了,标记一下,等待强人解答。



板凳

while( *++p != LAST_ARG )
  *p>result  ?  result= *p  :  0 ;
问题可能出在这

3 楼

因为对于C/C++中的...参数,标准中规定如果是float型,则自动转成double型,故你无法用float指针正常读取。

4 楼

函数的参数列表中有...,那么调用函数时要对相应的实参做Integer Promotion,此外,相应的实参如果是float型的也要被提升为double型,这条规则称为Default Argument Promotion。

用不上可变参数,这条还真忽视了。

5 楼

 

6 楼

低地址存低位,高地址存高位

7 楼

[quote]低地址存低位,高地址存高位[/quote]
恩,这一点我确实疏忽了。不过,那段代码并不要修改,只是比较的时候以美8bits为单位,明天我再仔细看看

8 楼

费这个劲,知道OLLDBG,或者IDA吗?跟踪一下程序就完了.再有,内存中只能存0或1所不同的是对内存操作的CPU指令不同,相同的内存如果用整数操作的指令操作CPU就会把存在这内存中的数当成整数,如果用浮点指令操作这块内存的话,CPU就会把这块内存中存的数当成浮点数,照你这个研究的方法,你是不是还得研究一下CPU架构什么的?

9 楼

确实是3楼和4楼说的那样,...参数中的float型会被提升为double型,可用double指针正确访问到它。
    还有6楼那句话让我很快找到了我的错误所在:在比较数据的时候把起始位置弄错了。

[quote]费这个劲,知道OLLDBG,或者IDA吗?[/quote]
又学知识了,以前还没用过工具来调试程序,今天试了下,感觉很好用!!!可能用起来不熟练,我觉得小问题直接从原代码中加入输出重要信息还是要简单一些。

[quote]还得研究一下CPU架构什么的?[/quote]
我觉得在研究参数传递的时候,数据是怎么存储不必知道得十分清楚,反正不管是float还是double型,只要起始地址正确,用同一个函数输出的0和1总是一定的。这种方法还有一个好处,可以写一个函数:如 自己设置float类型的每一个字节上的数据来确定这个float型的数。

10 楼



The Warcraft [url=http://www.toppowerlevel.net]wow power leveling[/url] Battlecry Mosaic is finally nearing completion and unlocked a new tile. The picture count reached 16,436 and a new milestone [url=http://www.mogxe.com/PowerLevel.php?gid=1]wow power leveling[/url] was reached, this time unlocking a piece done by Samwise that depicts a vile [url=http://www.toppowerlevel.net/powerlist.php?fid=688]wow power leveling[/url] Burning Legion Fel Orc.[url=http://www.toppowerlevel.net/gamelist.php?fid=7656]aion kina[/url]
There are only 4 tiles left to complete mosaic, [url=http://www.mogxe.com]buy wow gold[/url] so why not head over to the official Warcraft Battlecry Mosaic site and submit your own photo?From the [url=http://www.mogxe.com]buy wow gold[/url] looks of it, this world event is going to [url=http://www.toppowerlevel.net/buy.php]gold in wow[/url] be much closer to what we saw last year (unlike the Love Is In the Air event), so previous experience [url=http://www.toppowerlevel.net/buy.php]wow gold eu[/url] should apply. We've also pulled out all the stops to make a fully featured [url=http://www.toppowerlevel.net/buy.php]wow gold cheap[/url] table with links to the locations of all the Elders, complete with lightboxed maps [url=http://www.toppowerlevel.net/buy.php]wow gold uk[/url] for each individual location, and overall maps for the whole continents. :)

我来回复

您尚未登录,请登录后再回复。点此登录或注册