您的位置:首页 > 其它

格式转换问题

2015-09-01 00:52 225 查看
最近发现了一道比较有趣的题目:

[code]void fun()  
{  
    unsigned int a = 2013;  
    int b = -2;  
    int c = 0;  
    while (a + b > 0)  
    {  
        a = a + b;  
        c++;  
    }  
    printf("%d", c);  
}
问:最后程序输出是多少?


乍一看,问题在于格式转换上,a+b 会先把b int 转成unsigned int,由于(unsigned)-2 = 0x1111 1110 也就是说a+nb不会小于0, 等于零也只有在a = 2,n = 1的情况下,于是程序会有栈溢出的问题存在。

想了想,还是总结一下格式转换的问题:

总的方向是:默认 小范围的往大范围的方式转换,比如

[code]int+double = double, unsigned int + int = unsigned int


大的往小的,需要格式转换,一般常用格式转换是(new_type) 比如 int a = (int)0.2f

或者是指针读取:

[code]struct IP{
    byte verson_hlen;
    byte service_type;
    short len;
    ……
};
void decode(char *ipData) {
    IP *p_ip = (IP*)ipData;
    printf("head length: %2d, total length: %d\n",
            p_ip->verson_hlen & 0x01 * 4, len);
}





其实 float => int 又与指针读取有什么区别呢? 不过是在float的地址上用int的指针读取的值(其实小数的存储方式有点特别,详情请看float的存储方式,所以这种想法还是欠妥,以及 在float与int的转换 里面你可以理解为什么判等的时候不常用小数,感兴趣的同学可以执行我下面的程序,会有意外收获,提示: 精度)

[code]#include "stdio.h"

int main() {

    if (0.6f == 0.6f)
        printf("0.6f == 0.6f\n");
    else
        printf("0.6f != 0.6f\n");

    if (0.6d == 0.6f)
        printf("0.6d == 0.6f\n");
    else
        printf("0.6d != 0.6f\n");

    if (0.5f == 0.5f)
        printf("0.5f == 0.5f\n");
    else
        printf("0.5f != 0.5f\n");

    if (0.5d == 0.5f)
        printf("0.5d == 0.5f\n");
    else
        printf("0.5d != 0.5f\n");

    return 0;
}


这里顺带提一下c++的四种类型转换:

这四种转换的用法一致:如

[code]int a = (int)0.2f;
int a = ***_cast<int>(0.2f)


有点像函数,而里面的<int>,有点像<T>模版

类型含义
static_cast其实就是常见的类型转换,类似于 int a = (int)1.2f 在转换的过程中由于精度四舍五入,自然可能会损失数据
reinterpreter_cast是将数据重新解释,类似于上文的IP decoder,由于是只是重新解释二进制数据,所以不会造成数据的损失
const_cast将const指针(或引用)类型转换为非const指针(或引用)指针const意味着什么
dynamic_cast多态类型转换常用,具有类型检查功能,一般用于下行转换(基类转为派生类)
上表参考

其实C++的四种类型转换是普通类型转换的俩种普例+俩种特例,附带某些功能(如去除const,类型检查)。

附:

const测试:

[code]#include "stdio.h"

int main()
{
    int num1 = 1;
    const int *a = &num1;
    printf("a is %d\n", *a);
    num1 ++;
    printf("num1++, a is %d\n", *a);

    int num2 = 10;
    a = &num2;
    printf("a is %d\n", *a);

//  int *b = a; //error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
    int *b = const_cast<int*>(a);
//  *a = *a + 1; //error: assignment of read-only location '* a'
//  printf("a is %d\n", *a);
    *b = *b + 1;
    printf("b is %d\n", *b);
    printf("a is %d\n", *a);

    return 0;
}
/**
a is 1
num1++, a is 2
a is 10
b is 11
a is 11
**/

int main()
{
    int num1 = 1;
    int * const a = &num1;
    printf("a is %d\n", *a);
    num1 ++;
    printf("num1++, a is %d\n", *a);

//  int num2 = 10;
//  a = &num2;  //error: assignment of read-only variable 'a'
//  printf("a is %d\n", *a);

    int *b = a;
    *a = *a + 1;
    printf("a is %d\n", *a);
    *b = *b + 1;
    printf("b is %d\n", *b);

    return 0;
}
/**
a is 1
num1++, a is 2
a is 3
b is 4
**/


const int * pint * const p
p is a (pointer to)(*) const intp is a const (pointer to)(*) int
read-only ‘* a’(内容)read-only ‘a’(指针)
从上方可以看出 对于 const int *p 不能直接修改*p, 只能通过指向的num1(非const)修改 或者从const_cast得到指针cp,修改*cp。也就是*p 只读,而p可读写。(一个烂例子:你可以选择不同地方住,但是住下来了,内容是不能变动的)

对于int * const p 不能修改p的指向(*p的地址、p变量的内容),但是可以修改*p的内容,虽然不能跟换p的指向(另一个烂例子:你住的地方不好更改,但是你可以布置一下家居)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: