精华内容
下载资源
问答
  • 最近在看《Computer Systems--A Programmer‘s Perspective》觉得有关C语言指针转换部分很有意思,虽然以前常使用类型转化可是却不知道底层(编译器?)到底怎么做的,于是从汇编角度学习了一下。使用工具GNU gcc-...

    最近在看《Computer Systems--A Programmer‘s Perspective》觉得有关C语言指针转换部分很有意思,虽然以前常使用类型转化可是却不知道底层(编译器?)到底怎么做的,于是从汇编角度学习了一下。使用工具GNU gcc-4.4.5,vim-7.2 ,Ubuntu10.10

    假如如下定义类型v和指针p,且使用类型转化:

     

    假如sizeof(src_t) > sizeof(dest_t),那么直接截取src_t中的低字节给dest_t。例如从int a转化为char b,由于这些局部变量都会存在stack上,那么就会有如下代码:可以看到就是简单的截取大变量的低字节部分给小的变量。注意其中设计到寄存器间接寻址。

     

    int main()
    {
        int a = 4;
        char *b;
        *b = (char)a;
    }//gcc -S file.c
    /*Assembly*/
    movl $4,-4(%ebp)
    movl -4(%ebp),%eax  #4 --> %eax
    movl %eax,%edx      #4 --> %edx
    movl -8(%esp),%eax  #把要存放结果的地址给%eax
    movb %dl,(%eax)     #类型转化
    


    假如sizeof(src_t) < sizeof(dest_t),就稍微复杂一点了,设计到高位扩展的问题,也就是如何补齐大变量大于小变量的那一部分。也可以使用指令movs(按源操作数符号位扩展)和movz(按零扩展)系列。

    (1)如果srt_t是无符号的数,如unsigned转化为long long可以看到仅仅是把高位全部清0了。当然如果dest_t 也是无符号数于此相同,见下面:

    int main()
    {
        int a = 4;
        long long *b;
        b = (long long)a; 
    }//gcc -S
    /*Assembly*/
    movl $4,12(%esp)
    movl 12(%esp),%eax  #4 --> %eax
    movl $0,%edx        #0 --> %edx
    movl 8(%esp),%ecx   #%ecx存放%esp+8中的指针,即*b存放在%esp+8中
    movl %eax,(%ecx)    #4 --> %esp+8中指针指向的地址中
    movl %edx,4(%ecx)   #再把上面所说的地址中的高4字节清0


    (2)如果srt_t是有符号数,而dest_t是无符号数,比如int 转化为unsigned long long,那么结果任然是有符号数,也即是不可能从小的有符号数转化得到大的无符号数:而dest_t如果也有符号则类似。

     

    结论:唯一值得注意的就是可能有时候会出现char --> unsigned int的情形,那么是得不到正确结果的。

    展开全文
  • 昨天在想写反转字符串的时候,自己写了一个转换两个字符类型的swap(): void myswap(char *a,char *b) { char tmp; tmp = *a; *a = *b; *b = tmp; } 然后想到C语言怎么实现泛型的swap?最终在网上找到了这位...

     昨天在想写反转字符串的时候,自己写了一个转换两个字符类型的swap():

    void  myswap(char *a,char *b)
    {
        char tmp;
        tmp = *a;
        *a = *b;
        *b = tmp;
    }

    然后想到C语言中怎么实现泛型的swap?最终在网上找到了这位大佬的答案:

    int swap(void* lhs, void* rhs, size_t sz) {
        void* temp = malloc(sz); // 如果有C99支持,可以用VLA
        if (!temp) {
            return -1;
        }
        memcpy(temp, lhs, sz);
        memcpy(lhs, rhs, sz);
        memcpy(rhs, temp, sz);
        free(temp);
        return 0;
    }
    
    作者:丁冬
    链接:https://www.zhihu.com/question/36960338/answer/69787641
    来源:知乎
    

     

    展开全文
  • C++——类型转换

    2017-11-19 16:16:30
    c语言里的基础类型,char,short,int,uint,long.ulong,float,double,他们在表达式里是有隐式类型转换运算时,默认转换为右值的最大类型,然后运算,得出结果后强转为左值的类型赋值给左值,期间char,short一定...

    c语言里的基础类型,char,short,int,uint,long.ulong,float,double,他们在表达式里是有隐式类型的转换,做运算时,默认转换为右值的最大类型,然后运算,得出结果后强转为左值的类型赋值给左值,期间char,short一定是先转换为int类型,而且基础类型里无符号大于有符号。C++里也满足这样的关系,但是现在有类了,类和基础数据类型怎么进行转换呢。

    如果基础数据类型想要转换成类类型,需要有转换构造函数,转换构造函数只有一个参数,而且参数的类型是基本类型或其他类类型。如果我们的参数是一个基本数据类型,那么只要是基本类型的数据都会强制转换为这个类型的值然后调用一个转换构造函数完成基础数据类型到类类型的转换。因为参数的类型可以是其他类类型,所有也可以完成类型到类型的转换。

    如果是类类型转换成基础数据类型,需要有类型转换函数,需要自己实现Type operator Type(){}的函数。此函数也可以完成类型到类型的转换。

    两者都是自动调用,而且都可以完成类类型之间的转换,所有如果两个类,右值的类类型有类型转换函数,左值的类类型有转换构造函数就会有二义性。还有当一个类类型的转换构造函数是基础类型时,不仅会自动调用而且还是有隐式类型的C语言的转换,我们想避免上述两者情况怎么办?

    对于后者,我们可以在转换构造函数前加上一个explicit关键词,告诉编译器,不要自动调用这个转换构造函数,要让使用者显示调用。这样虽然我们没有完全解决了基础数据类型之间的相互转换,但是我们通过显示调用这个函数提示使用者一定考考虑是否使用此转换构造函数。

    对于前者,我们有两种方法,一是对转换构造函数使用关键字explicit,这样编译器不能再自动调用类型转换函数,所有只能调用转换构造函数,二,为了避免类型转换函数也自动的调用我们通常不使用类型转换函数,而是在类的成员方法里,提供toType()的成员函数去完成类型转换的功能。

    展开全文
  • C++中的类型转换

    2017-03-09 11:47:34
    一、概述笔者曾经面试的...后来我想到了类型转换const_cast 去掉const属性转换。其实这道题我也不知道对了没,回来也没有上网查过资料,借用一句话描述一下我这种性格吧,“不要和我比懒,我懒得和你比”。好了,废话

    一、概述

    笔者曾经面试的时候遇到一个问题,在C++怎么改变const修饰的常量的值,当时我还想了一会,C语言的const修饰的常量是假常量,是可以通过指针修改的,而C++中的常量那可是一个真的常量,怎么修改呢!后来我想到了类型转换const_cast 去掉const属性转换。其实这道题我也不知道做对了没,回来也没有上网查过资料,借用一句话描述一下我这种性格吧,“不要和我比懒,我懒得和你比”。好了,废话不多说,让我们进入正题吧。我们都知道C语言的类型转换,其实C++中也有类型转换。C++提供了四种类型转换,分别适应不同的场合。

    • static_cast ——>静态类型转换。
    • reinterpreter_cast ——>重新解释类型转换。
    • dynamic_cast ——>子类和父类之间的多态类型转换。
    • const_cast ——>去掉const属性转换。

    二、转换方式及相关案例

    1、static_cast 静态类型转换

    所谓的静态,即在编译期内即可决定其类型的转换,用的也是最多的一种
    代码格式

    static_cast<目标类型> cast
    

    案例:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        double dPi = 3.1415926;
        int iPi1 = (int)dPi;
        int iPi2 = dPi;
    
        int iPi3 = static_cast<int> (dPi);  
    
        cout << "dPi:" << dPi << "iPi1:" << iPi1 << "iPi2:" << iPi2 << "iPi3:" << iPi3 << endl;
    
        return 0; 
    }
    

    2、dynamic_cast 子类和父类之间的多态类型转换

    形式

    dynamic_cast<目标类型> (标识符)
    

    案例:

    #include <iostream>
    using namespace std;
    
    class Animal
    {
    public:
        virtual void cry() = 0;
        virtual void doWork() = 0;
    };
    
    class Cat : public Animal
    {
    public:
        virtual void cry()
        {
            cout << "喵喵~~~~" << endl;
        }
        virtual void doWork()
        {
            cout << "抓老鼠" << endl;
        }
    
    };
    
    class Dog :public Animal
    {
    public:
        virtual void cry()
        {
            cout << "汪汪~~" << endl;
        }
        virtual void doWork()
        {
            cout << "看家" << endl;
        }
    };
    
    int main(void)
    {
        Animal *animal = NULL;
        animal = new Dog;
        animal->cry();
        animal->doWork();
        cout << " -----" << endl;
        Dog * dog = NULL;
        dog = dynamic_cast<Dog*>(animal); 
        if (dog != NULL)
        {
            cout << "转换成功" << endl;
            dog->cry();
            dog->doWork();
        }
        else 
        {
            cout << "转换失败" << endl;
        }
        Cat *cat = NULL;
    
        if (cat != NULL)
        {
            cout << "转换成功" << endl;
            cat->cry();
            cat->doWork();
        }
        else
        {
            cout << "转换失败" << endl;
        }
        delete animal;
        return 0;
    }
    

    3、const_cast 去掉const属性转换

    目标类类型只能是指针或引用
    形式:

    const_cast<目标类型> (标识符)
    

    案例:

    const int a = 10; 
    const int *a_p = &a; 
    //把a_p的const 属性去掉
    int *a_p1 = const_cast<int*>(a_p);
    

    4、reinterpret_cast 重新解释类型转换

    interpret 是解释的意思,reinterpret 即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。
    形式:

    reinterpret_cast<目标类型> (标识符)
    

    案例:

    #include <iostream>
    
    using namespace std;
    
    class Animal
    {
    public:
        virtual void cry() = 0;
        virtual void doWork() = 0;
    };
    
    class Cat : public Animal
    {
    public:
        virtual void cry()
        {
            cout << "喵喵~~~~" << endl;
        }
        virtual void doWork()
        {
            cout << "抓老鼠" << endl;
        }
    
    };
    
    class Dog :public Animal
    {
    public:
        virtual void cry()
        {
            cout << "汪汪~~" << endl;
        }
        virtual void doWork()
        {
            cout << "看家" << endl;
        }
    };
    
    class Tree
    {
    public:
        Tree(int age)
        {
            this->age = age;
        }
        virtual void print()
        {
            cout << "我是大叔" << endl;
        }
        int age;
    };
    
    
    int main(void)
    {
        Animal *animal = new Dog;
        //是c++中真正的 强制转换, 也是最危险的转换方式。
        Tree* tree = reinterpret_cast<Tree*>(animal); 
        if (tree != NULL)
        {
            cout << "转换成功" << endl;
            cout << tree->age << endl;
            tree->print();
        }
        else
        {
            cout << "转换失败" << endl;
        }
        return 0;
    }
    

    三、总结

    程序员要清除的知道: 要转的变量,类型转换前是什么类型,类型转换后是什么类型。转换后有什么后果。一般情况下,不建议进行类型转换。

    展开全文
  • C语言基础

    2018-03-12 18:39:25
    1、混合运算应该怎么计算:...2、sizeof和strlen的区别sizeof是操作符,可以用类型做大小,计算的是类型占内存大小strlen是函数,只能用char*参数,且必须以'\0'结尾,计算的是字符串长度3、#include&lt;head...
  • C语言类型转换有几种方式:1.(expression).在表达式外边加括号,由编译器来决定怎么改变。2.new_type(expression).强制类型括号住表达式。3.(new_type)expression.括号住强制类型。4.C语言允许的内置转换。这些...
  • C语言编程要点

    2017-09-18 00:10:37
    2.14. 什么时候不应该使用类型强制转换(typecast)? 27 2.15. 可以在头文件中说明或定义变量吗? 27 2.16. 说明一个变量和定义一个变量有什么区别? 27 2.17. 可以在头文件中说明static变量吗? 28 2.18. 用const说明...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    答:对于复杂而开发时间紧的项目时,可以采用C语言,但前提是要求对该MCU系统的C语言和C编译器非常熟悉,特别要注意该C编译系统所能支持的数据类型和算法。虽然C语言是最普遍的一种高级语言,但不同的MCU厂家其...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    我试了类型转换,但是不行。 第5章 空指针 空指针和空指针常量 5.1 臭名昭著的空指针到底是什么? 5.2 怎样在程序里获得一个空指针? 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的内部...
  • 我试了类型转换, 但是不行。 * 6. 空 (null) 指针 o 6.1 臭名昭著的空指针到底是什么? o 6.2 怎样在程序里获得一个空指针? o 6.3 用缩写的指针比较 ``if(p)" 检查空指针是否可靠?如果空指针的内部表达不是 ...
  • 我试了类型转换,但是不行。 第5章 空指针 空指针和空指针常量 5.1 臭名昭著的空指针到底是什么? 5.2 怎样在程序里获得一个空指针? 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的内部表达不是0...
  • 嵌入式面试题——有意思的C语言

    千次阅读 2017-03-10 00:01:29
    1.要对绝对地址0x100000赋值,我们可以利用(Unsigned int *)0x100000=1234,那么我们要跳转到绝对地址是0x100000去执行,怎么做? (1)先转换为函数指针(void(*)()) 0x100000 (2)然后加一个*号调用这个函数 ...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    我试了类型转换,但是不行。 52 第5章 空指针 53 空指针和空指针常量 53 5.1 臭名昭著的空指针到底是什么? 53 5.2 怎样在程序里获得一个空指针? 54 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?...
  • 我试了类型转换,但是不行。 52 第5章 空指针 53 空指针和空指针常量 53 5.1 臭名昭著的空指针到底是什么? 53 5.2 怎样在程序里获得一个空指针? 54 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?...
  • 解释型语言一般不需要声明就可以使用,因为它们先默认当做字符串,在需要用的时候再转换成需要的类型。 Q: 自动变量未初始化时值为什么是不确定的? A:堆栈数据的不确定性是其本质原因。没有任何操作系统会在...
  • 我试了类型转换,但是不行。  第5章 空指针  空指针和空指针常量  5.1 臭名昭著的空指针到底是什么?  5.2 怎样在程序里获得一个空指针?  5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的...
  • 我试了类型转换,但是不行。 第5章 空指针 空指针和空指针常量 5.1 臭名昭著的空指针到底是什么? 5.2 怎样在程序里获得一个空指针? 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的内部...
  • 我试了类型转换,但是不行。 第5章 空指针  空指针和空指针常量  5.1 臭名昭著的空指针到底是什么?  5.2 怎样在程序里获得一个空指针?  5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的...
  • 我试了类型转换,但是不行。 第5章 空指针 空指针和空指针常量 5.1 臭名昭著的空指针到底是什么? 5.2 怎样在程序里获得一个空指针? 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空指针的内部表达不是0...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    我试了类型转换, 但是不 行。. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 5 空(null) 指针21 5.1 臭名昭著的空指针到底是什么? . . . . . . . . . . . . . . . . . . . 21 5.2 怎样在...
  • 我试了类型转换,但是不行。 81 第5章 空指针 82 空指针和空指针常量 82 5.1 臭名昭著的空指针到底是什么? 82 5.2 怎样在程序里获得一个空指针? 83 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空...
  • 我试了类型转换,但是不行。 81 第5章 空指针 82 空指针和空指针常量 82 5.1 臭名昭著的空指针到底是什么? 82 5.2 怎样在程序里获得一个空指针? 83 5.3 用缩写的指针比较“if(p)”检查空指针是否有效?如果空...
  • 为什么有些代码小心地把 malloc 返回的值转换为分配的指针类型。 37 7.10 在调用 malloc() 的时候, 错误 “不能把 void * 转换为 int *” 是什 么意思? . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....
  • C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。 C++语言工作原理 C++语言的程序因为要体现...
  • 主要是构思解决问题的主要思路,明确“怎么做(How to do?)”。采用自顶向下方法,确定各个功能,用模块图描述系统的功能。确定各个功能对应的函数,以及函数之间的关系并能用流程图描述函数的算法。 3、程序调试和...
  • 假如现在有一个.c的文件,它里面有C语言的注释(/…/),C++的注释(//),当然也有正常的代码了,现在我们想要把里面的注释统一一下,将C语言注释全部转换为C++的注释,该怎么做呢? 思路: 我们可以这么想,它...
  • JavaScript初阶(二)

    2017-11-29 18:13:00
    面向过程:每一步我们该怎么做,如C语言 面向对象:包含面向过程,但更重要的是用什么方法处理,结构化更强。 显示类型转换  typeof能够区分六种数据类型,他返回六种值,分别是Object,number,string,...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

c语言类型转换怎么做

c语言 订阅