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使用需要注意
- dynamic_cast是在运行时检查,用于进行安全的向下转换。如果源和目标类型没有继承和被继承关系,编译器会报错;必须判断返回值是否为NULL来确认转换是否成功。
- dynamic_cast是4个转换中唯一的RTTI操作符,提供运行时类型检查。
- 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
网友评论