C++学习(44)

来源:互联网 发布:win7下制作mac启动u盘 编辑:程序博客网 时间:2024/05/22 15:33

1.分析下列程序:

#include<iostream>#include<cstdlib>#include<string.h>using namespace std;int main(int argc,char **argv) {  struct s{    int x:3;    int y:4;    int z:5;    double a;  };  cout<<sizeof(s);  return 0;}

分析:需要看清楚该结构体中是位操作,三个变量共占用一个int类型的大小,int类型占用4个字节,double占用8个字节。为了实现内存对其,int类型需要填充4个字节的长度。

 

位域只要是用来节约内存使用的,通常都是在嵌入式中使用它,当我觉得一个结构体中的变量在某一个范围内的时候,就可以指定位的多少。例如int是4B,32位,而我做嵌入式的时候,3位就够了0-7取值范围,所以我就可以定义位域。所以本题的就是3+4+5=12位,int是32位,所以公用一个int型。

 

2.下列程序执行结果:没有输出结果,出错。

#include<iostream>#include<cstdlib>#include<string.h>using namespace std;class parent {public:virtual void output();};void parent::output(){printf("parent!");}class son:public parent {public:virtual void output();};void son::output() {printf("son!");}int main(int argc,char *argv) {son s;memset(&s,0,sizeof(s));parent &p=s;p.output();return 0;}
分析:void *memset(void *s, int ch, size_t n);函数解释:将s中前n个字节 (typedefunsigned int size_t)用ch替换并返回s.

 

作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法,通常为新申请的内存做初始化工作.

 

3.分析下列程序:

#include<iostream>#include<cstdlib>#include<string.h>using namespace std;int main(int argc,char **argv) {  char*p1="hello";  char*p2="world";  char *p3="apiece of cake";  char*str[]={p1,p2,p3};  printf("%c",*(str[0]+1));  return 0;}


分析:str[0]为p1 p1指向的是"hello" p1指针+1 前进一位指向字符e。最后输出e。

 

4.a.c_str()是将a转化为了c语言风格的字符串,c语言风格字符串实际上就是一个字符数组,c_str()返回的是指向字符数组的指针,当用==比较时,为比较指针对应的内存地址,abc的内存地址都不相同,所以比较的时候都为false,如果想比较字符串的话可以加上*,改成if(*a.c_str()==*b.c_str()),这样就能返回true。

 

分析二:

1).c_str()返回值是const char*,返回一个指向正规C字符串的指针;

2).string b=a是C++中string类的赋值操作,b会开辟一个与a同等长度的内存空间,把a的字符串拷贝到b的内存空间中;

所以if(a.c_str()==b.c_str())比较的是2个const char*,很显然是不等的。

 

5.static_cast的用法

static_cast < type-id > ( expression )

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性

它主要有如下几种用法:

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的

 

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。

 

注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。

 

C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。因此,被做为显式类型转换使用。

 

C++中的reinterpret_cast主要是将数据从一种类型的转换为另一种类型。所谓“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式的重新解释。

 

四类强制转换

static_cast(编译器可实现的隐式转换或类层次间的下行转换)、

dynamic_cast(操作数只能为类指针或类引用)、

const_cast(去除const)、reinterpret_const(一般意义强制转换)

 

注意:

无关类型指针之间是无法转换的。

直接赋值,无法进行隐式转换。

----------------------------------------------------------------------------------

点击打开链接

C++四种类型转换(转载)

类型转换有c风格的,当然还有c++风格的。c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆。所以c++为了克服这些缺点,引进了4新的类型转换操作符,他们是1.static_cast  2.const_cast  3.dynamic_cast  4.reinterpret_cast.

1).static_cast最常用的类型转换符,在正常状况下的类型转换,如把int转换为float,如:int i;float f; f=(float)i;或者f=static_cast<float>(i);

2).const_cast用于取出const属性,把const类型的指针变为非const类型的指针,如:const int *fun(int x,int y){}  int *ptr=const_cast<int *>(fun(2.3))

3).dynamic_cast该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。dynamic_cast与static_cast具有相同的基本语法,dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。如:

class C

{
  //…C没有虚拟函数
};
class T{
  //…
}
int main()
{
  dynamic_cast<T*> (new C);//错误
}
此时如改为以下则是合法的:
class C

{
public:
  virtual void m() {};// C现在是 多态
}

4).reinterpret_cast

interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。如:int i; char *ptr="hello freind!"; i=reinterpret_cast<int>(ptr);这个转换方式很少使用。



原创粉丝点击