位运算

作者: geaus | 来源:发表于2016-05-05 10:28 被阅读0次
printf("%f", 5);

上面语句打出的结果为0.000000。原因是printf根据%f会认为参数是double型,因此从栈中读8个字节。而5是int型,内存访问越界,发生不可预料的情况,处理时打印0。

//结构体位制
struct a{
    int x : 1;      //这种语法是指定x的bit位数,所以x只有1位
    int y : 2;
    int z : 33;     //z指定33位,但因为是int只有32位,所以报错
}

下面代码哪个等同于int i=(int) p; (p类型为char *)?

A int i =  dynamic_cast<int>(p)
B int i =  static_cast<int>(p)
C int i = const_cast<int>(p)
D int i=reinterpret_cast<int>(p)

选D,dynamic_cast用于父类子类间的指针类型转换,static,const的功能也用于这,只有reinterpret_cast(不改变原数据的值),这里是将指针p的值(某地址)按int赋值给i。

static_cast, const_cast, dynamic_cast, reinterpret_cast
static_cast用于类型转换,如将int转换为double以便让包含int的表达式产生浮点数值的结果。

static_cast<double>(firstNumber)/secondNumber

不能用于将double转为指针或者struct转int,不能去除const属性。
const_cast最普通的用途就是去掉对象的const属性。

class B{
public:
    int m_iNum;
};
int main(){
    B b0;
    b0.m_iNum=100;
    const B b1=b0;
    cout<<b0.m_iNum<<" "<<b1.m_iNum<<endl;
    const_cast<B&>(b1).m_iNum=200;
    cout<<b0.m_iNum<<" "<<b1.m_iNum<<endl;
    return 0;
}

static_cast和reinterpret_cast操作修改了操作数类型。static_cast编译时使用类型信息执行转换,相对安全。reinterpret_cast仅仅是重新解释对象的比特模型,没有进行二进制转换,比较危险。

int n=9;
static_cast<double>(n);  //这里会为n补位
reinterpret_cast<double>(n);    //不会补位

dynamic_cast使用需要注意

  1. dynamic_cast是在运行时检查,用于进行安全的向下转换。如果源和目标类型没有继承和被继承关系,编译器会报错;必须判断返回值是否为NULL来确认转换是否成功。
  2. dynamic_cast是4个转换中唯一的RTTI操作符,提供运行时类型检查。
  3. dynamic_cast不是强制转换,而是咨询性质的转换,不能转换的话返回NULL。

对于类中的成员函数,如果不涉及类成员变量,则即使该类的指针为NULL时,也可以通过该指针调用该成员函数。

class B{
public:
    void disp(){ cout<<"hello world"<<endl; }
};
int main(){
    B *b0=NULL;
    b0->disp();
    return 0;
}

但如果该类继承了父类,且该方法为虚函数,则调用会出错,因为调用虚方法要求对象有一个虚函数表指针。

class A{
public:
    virtual void disp(){ cout<<"hello A"<<endl; }
};
class B : public A{
public:
    virtual void disp(){ cout<<"hello B"<<endl; }
};
int main(){
    B *b0=NULL;
    b0->disp();
    return 0;
}

建立一个联合体,由char和int类型组成

union{
    unsigned char a;
    unsigned int i;
}u;
u.i=0xf0f1f2f3;
cout<<hex<<u.i<<endl;       //输出f0f1f2f3
cout<<hex<<u.a<<endl;       //输出f3

说明内存中数据低位字节存入低地址,高位字节存入高地址,数据的地址采用它的低地址表示。
当一个变量的值可能会在编译器的控制或监测之外被改变时,那么它应该声明为volatile。因此编译器执行的例行优化行为不能应用在该指定为volatile变量上。这样,优化器在用到这个变量时都必须每次的重新读取这个变量的值,而不是使用保存在寄存器的备份。
可以建立const volatile变量,这样这个变量不能被程序员改变,但可以通过外面的工具改变。
const意味着“只读”。
下面的函数有什么错误?

int square(volatile int *ptr){ return *ptr * *ptr; }

上面的代码本意是返回ptr的平方,但由于执行时ptr可能会改变,类似于下面的代码

int square(volatile int *ptr){
    int a=*ptr;
    int b=*ptr;
    return a*b;
}

正确的应该如下

int square(volatile int *ptr){
    int a=*ptr;
    return a*a;
}

小尾字节序和大尾字节序
前者是指CPU对操作数的存放方式是从低字节到高字节即低位字节存放在低地址,高位字节存放在高地址。后者则相反,低地址存高位字节,高地址存低位字节。
或者解释为,沿着地址向上的方向,小尾先存低后存高;大尾先存高后存底。

//存储0x1234
//小尾
0x4000 0x34
0x4001 0x12
//大尾
0x4000 0x12
0x4001 0x34

static关键字的作用:

staic_Image.png

相关文章

  • 3、小众运算符の大课堂(一)

    较为简单の位运算符: & 位与运算| 位或运算^ 位异或运算~ 位取反运算 举例: 要做位运算,首先要把数据转...

  • 位运算及其应用

    内容概要: 位运算基本操作 基于位运算的状态压缩 位运算经典应用 位运算解N皇后问题 位运算 符号描述规则&与1&...

  • 位运算及用位运算实现权限控制

    请自行补习位运算相关知识 位运算 位运算示例 权限控制

  • 开发基础随笔之位运算符(Bitwise Operators)

    位运算符,属于算术运算符 按位逻辑运算符: 位移运算符: 位运算符的运算数只能是整数 位移运算符:按位左移 a<<...

  • 强大的位运算符

    位取反运算符 位取反运算符(~)是对所有位的数字进行取反操作位取反运算符.png 位与运算符 位与运算符(&)可以...

  • 位运算

    位运算 1. &:按位与 规律:一假则假任何位上的数和1相&得到的结果还是那个数 2. |:按位或 规律:一真则真...

  • 位运算

    https://leetcode.com/problems/gray-code/description/这个位运算...

  • 位运算

    位运算符比一般的算术运算符速度要快,而且可以实现一些算术运算符不能实现的功能。如果要开发高效率程序,位运算符是必不...

  • 位运算

    1.不用加减乘除做加法 解法:分为三步①各位相加不进位,即先按位异或;②做进位,按位与并左移位;③结果相加,直至没...

  • 位运算

    位运算不仅可以简化某些复杂的操作,而且具有更快的计算速度。典型的应用就是除法,交换两个数值,以及在一个数组中寻找只...

网友评论

      本文标题:位运算

      本文链接:https://www.haomeiwen.com/subject/mikdrttx.html