指针强制转换

合集下载

强制转型

强制转型

dynamic_cast运算符dynamic_cast可以针对两种数据类型做强制转换:指针类型和引用类型。

这两种类型的情况是不一样的。

下面讨论如下:1、对指针的强制转换dynamic_cast<T*>(p);如果p的类型为T*,或者为D*,且T是D的一个可以访问的基类,结果跟我们直接将p 赋给一个T*是一样的。

(这是向上类型转换的情况)。

dynaimic_cast的专长是用于那些编译器无法确定转换正确性的情况。

在这种情况下dynamic_cast将查看被p指向的对象(如果有的话),如果这个对象属于类T,或者有唯一的基类T,那么dynamic_cast就返回指向该对象的类型为T*的指针。

否则就返回0。

如果p 的值为0,则dynamic_cast<T*>(p)也返回0。

如果要做向下的类型转换,或者兄弟类之间做交叉转换,则要求p是一个到多态类型的指针或引用。

但是转换的目标类型不一定是支持多态的。

因为如果p的类型不是T的,那么返回值为0,这样的话,我们对dynamic_cast<T*>(p)的返回值必须做显示的检查。

对于指针p,dynamic_cast<T*>(p)可以看成一个疑问:p所指向的对象的类型是T吗?2、对引用的强制转换因为我们能合法的假定一个引用总是引用着某个对象,因此对引用r做dynamic_cast<T&>(r)不是提问,而是断言:“由r引用的对象的类型是T”。

对于引用的dynamic_cast的结果,隐式的由dynamic_cast去做检查,如果对引用的dynamic_cast不具有所需要的类型,就会跑出一个bad_cast异常。

在对动态指针强制转换和动态引用强制转换结果方面的差异,所反应的正是指针和引用之间的根本性差异。

////////////////////////////////////////////////////////////////////C++的数据类型转换dynamic_cast2007年04月26日星期四下午 06:13(一)在使用C++编程时,经常要用到不同数据类型之间的类型转换,可能大家对C 语言的类型强制转换比较熟悉,就是在表达时前面加一个“(强制转换类型)”。

C++对象指针转换

C++对象指针转换

在C++中存在两种转换:隐式转换和显式转换(强制转换)。

一、隐式类型转换C++定义了一组内置类型对象之间的标准转换,在必要时它们被编译器隐式地应用到对象上。

隐式类型转换发生在下列这些典型的情况下;1、在混合类型的算术表达式中。

在这种情况下,最宽的数据类型成为目标转换类型。

这也被称为算术转换arithmetic conversion 例如:int ival = 3;double dval = 3.14159;// ival 被提升为double 类型: 3.0 (是一种保值转换)ival + dval;2、用一种类型的表达式赋值给另一种类型的对象。

在这种情况下,目标转换类型是被赋值对象的类型。

例如,在下面第一个赋值中文字常量0 的类型是int 它被转换成int*型的指针表示空地址在第二个赋值中double 型的值被截取成int 型的值。

// 0 被转换成int*类型的空指针值int *pi = 0;// dval 被截取为int值3 (这不是保值转换),一般情况下编译器会给出warning.ival = dval;3、把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同。

在这种情况下,目标转换类型是形式参数的类型。

例如:extern double sqrt( double );// 2 被提升为double 类型: 2.0cout4、从一个函数返回一个表达式,表达式的类型与返回类型不相同。

在这种情况下,目标转换类型是函数的返回类型。

例如:double difference( int ival1, int ival2 ){// 返回值被提升为double 类型return ival1 - ival2;}二、显示转换(强制转换)(一)、旧式强制类型转换:由static_cast,cons_cast 或reinterpret_cast 强制转换符号语法,有时被称为新式强制转换符号,它是由标准C++引入的。

c 强制类型转换 const

c 强制类型转换 const

c 强制类型转换 const
在C语言中,强制类型转换是一种将一个数据类型转换为另一
个数据类型的操作。

在进行强制类型转换时,我们可以改变一个变
量的数据类型,以便在表达式中使用该变量。

在进行强制类型转换时,我们可以使用强制类型转换运算符来实现,它的一般形式是(type_name) expression,其中 type_name 是我们希望将expression 转换为的类型。

在进行强制类型转换时,我们需要注意
以下几点:
1. 强制类型转换可能会导致数据丢失,当我们将一个较大的数
据类型转换为一个较小的数据类型时,可能会导致数据丢失。

例如,将一个浮点数转换为整数时,小数部分将被截断。

2. 强制类型转换可能会改变数据的含义,有时候,我们可能会
将一个数据类型转换为另一个数据类型,这可能会改变数据的含义。

例如,将一个指针转换为整数,可能会丢失指针所指向的对象的信息。

当我们进行 const 强制类型转换时,我们可以使用
const_cast 运算符来实现。

const_cast 是 C++ 中的一个运算符,
它可以用来移除对象的 const 属性,从而允许修改被 const 修饰的对象。

但是需要注意的是,对于 const 对象,我们应该谨慎地使用 const_cast 运算符,因为这可能会导致未定义的行为。

总的来说,强制类型转换是一种有用的工具,但是在使用时需要谨慎,以避免可能导致的数据丢失和未定义的行为。

函数指针强转

函数指针强转

函数指针强转
函数指针强转,是指将一个函数指针数据类型转换为另一个函数指针
数据类型。

在C语言中,函数指针是指向函数的指针变量,可以将函
数指针作为参数传递给其他函数,也可以将函数指针作为返回值返回。

一般情况下,函数指针强转是指将一个函数指针数据类型转换为另一
个函数指针数据类型,这可以用于将指向不同函数的指针强制转换为
相同的类型,这样可以在编译时避免出现类型不匹配的问题。

在C语言中,函数指针强转的语法格式如下:
(return_type (*new_type)(arguments)) pointer_expression;
其中,return_type表示函数的返回值类型,new_type表示需要将函数指针转换为的新类型,arguments表示函数的参数类型,
pointer_expression表示需要进行强制类型转换的函数指针。

需要注意的是,将函数指针强转时,需要确保转换后的函数指针可以
正确地执行指向的函数。

如果强制类型转换不正确,可能导致程序崩
溃或者出现其他错误。

除了将函数指针强转为相同的函数指针类型之外,还可以将其强制转换为void类型的函数指针,这可以使用在需要将函数指针参数传递给不同的函数时,将其作为通用的参数类型传递。

总之,函数指针强转可以用于将不同类型的函数指针转换为相同的类型,以便在编译时避免类型不匹配的问题。

但需要注意,必须确保转换后的函数指针可以正确地执行指向的函数。

c 函数指针 强制转换 参数个数不对

c 函数指针 强制转换 参数个数不对

在C语言中,函数指针是一种特殊类型的指针,可以用来存储和传递函数的地址。

函数指针可以在编译时或者运行时被调用,并通过参数和返回值来传递数据。

强制类型转换是将一个类型的值转换为另一个类型。

在C语言中,强制类型转换可以使用强制类型转换运算符(`(type)`)来完成。

参数个数不对是指在调用函数时,传递给函数的参数数量与函数定义中的参数数量不匹配。

这可能会导致编译错误或者运行时错误。

如果将函数指针强制转换并传递参数个数不对,会导致以下几种情况:
1. 编译错误:如果参数个数与函数定义中的参数数量不匹配,编译器会报错,导致编译失败。

2. 运行时错误:如果参数个数与函数定义中的参数数量不匹配,但编译器没有报错,那么在运行时可能会出现错误。

这可能会导致程序崩溃或者出现未定义的行为。

3. 未定义行为:如果函数指针强制转换后,调用的函数和原始函数具有不同的参数个数和类型,那么可能会出现未定义的行为。

这可能会导致程序出现不可预测的结果或错误。

因此,在使用函数指针时,应该确保传递给函数的参数个数和类型与函数定义中的参数个数和类型一致,以避免出现编译错误、运行时错误或未定义行为。

C++强制类型转换

C++强制类型转换
const_cast
用法:const_cast<type_id> (expression) 该运算符用来修改类型的 const 或 volatile 属性。除了 const 或 volatile 修饰之 外, type_id 和 expression 的类型是一样的。 一、常量指针被转化成非常量指针,并且仍然指向原来的对象; 二、常量引用被转换成非常量引用,并且仍然指向原来的对象; 三、常量对象被转换成非常量对象。 Voiatile 和 const 类试。举如下一例: class B{ public: int m_iNum; } void foo(){ const B b1; b1.m_iNum = 100; //comile error B b2 = const_cast<B>(b1); b2. m_iNum = 200; //fine } 上面的代码编译时会报错,因为 b1 是一个常量对象,不能对它进行改变; 使用 const_cast 把它转换成一个非常量对象,就可以对它的数据成员任意改变。 注意:b1 和 b2 是两个不同的对象。
static_cast
用法:static_cast < type-id > ( expression ) 该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换 的安全性。它主要有如下几种用法: ①用于类层次结构中基类和子类之间指针或引用的转换。 进行上行转换(把子类的指针或引用转换成基类表示)是安全的; 进 行 下 行 转 换( 把 基 类 指 针 或 引 用 转 换 成 子 类 表 示 )时 ,由 于 没 有 动 态 类 型 检 查 , 所以是不安全的。 ②用于基本数据类型之间的转换,如把 int 转换成 char,把 int 转换成 enum。这 种转换的安全性也要开发人员来保证。 ③把空指针转换成目标类型的空指针。 ④把任何类型的表达式转换成 void 类型。 注意:static_cast 不能转换掉 expression 的 const、volitale、或者__unaligned 属性。 C++中 static_cast 和 reinterpret_cast 的区别 C++primer 第五章里写了编译器隐式执行任何类型转换都可由 static_cast 显示 完成;reinterpret_cast 通常为操作数的位模式提供较低层的重新解释 1、C++中的 static_cast 执行非多态的转换,用于代替 C 中通常的转换操作。因 此,被做为隐式类型转换使用。比如:

c语言结构体指针强制类型转换

c语言结构体指针强制类型转换

c语言结构体指针强制类型转换
在C语言中,结构体是一种自定义数据类型,它由多个变量(成员)组成。

通常情况下,我们需要使用结构体指针来操作结构体变量。

但是有时候我们需要将一个结构体指针强制类型转换为另一个结构
体指针类型,以便于对其进行不同的操作。

C语言中的强制类型转换使用了一个特殊的符号“()”,格式如下:
(目标类型)表达式
其中,目标类型是要转换成的类型,表达式则是要进行转换的值。

在进行结构体指针的强制类型转换时,我们需要注意以下几点:
1. 转换后的结构体指针类型必须与原类型有相同的成员变量或者成员变量的类型,否则会导致程序运行错误。

2. 强制类型转换只改变指针类型,不改变指针所指向的内存区域,因此需要保证转换后的指针指向的内存区域是合法的。

3. 在进行结构体指针的强制类型转换时,我们应该尽量避免对指针所指向的内存区域造成不必要的影响,以免引起程序运行错误或安全问题。

总之,结构体指针的强制类型转换是C语言中非常重要的一个操作,需要在程序中谨慎使用,以确保程序的正确性和安全性。

- 1 -。

c语言强制类型转换的方法和原则

c语言强制类型转换的方法和原则

c语言强制类型转换的方法和原则
C语言中的强制类型转换可以通过使用类型转换运算符来实现,即将要转换的目标类型放在圆括号中,紧跟着要转换的表达式。

强制类型转换的原则如下:
1. 在进行类型转换之前,需要确保转换是安全和合理的。

比如,将一个较大的整数类型转换为较小的整数类型可能导致数据溢出或精度丢失。

2. 强制类型转换可以用于基本数据类型(如整数、浮点数)之间的转换,也可以用于指针类型之间的转换。

3. 当进行指针类型之间的转换时,需要格外注意,确保指针类型的大小相同或兼容。

否则,可能会导致访问越界或产生未定义的行为。

4. 在进行强制类型转换时,应当尽量避免对指针类型进行转换,特别是将一个指向非相关类型的指针转换为另一个指针类型,因为这可能会破坏内存的完整性及程序的健壮性。

5. 强制类型转换应该谨慎使用,只在必要时才使用。

过多地依赖强制类型转换可能导致代码的可读性和可维护性下降,同时也增加了代码出错的风险。

总之,强制类型转换是一种强制改变数据类型的操作,但需要谨慎使用,确保转换的安全性和合理性。

在进行强制类型转换时,应遵循上述原则,并尽量保持代码的简洁和易读。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、指针类型转换请使用static_cast、dynamic_cast等操作
2、指针变量(不管那种指针),大小都是四个字节,内容就是指向的对象的首地址。

不同类型指针不同点就是对首地址之后的那块内存会做不同解释。

建议你看看《Inside C++ Object Model》里面关于指针的内容,里面有清晰的说明
int * pi = new int;
pi 指向了一块内存的首地址,这块内存应该有sizeof(int)个字节,
由于pi是int *类型,所以通过pi进行的操作,编译器都认为pi的内容是一个有sizeof(int)个字节的int 型变量的首地址,所以*pi = 4,遇到这样的操作,编译器产生的代码就是把4这个数付到pi所指的四个字节里。

char * pc = (char *)pc; //建议这样写char * pc = static_cast <char *> (pc);
*pc = '4 ';
由于pc是char *类型,所以通过pc进行的操作,编译器都认为pc的内容是一个有sizeof(char)个字节的char型变量的首地址,所以*pc = '4 ',遇到这样的操作,编译器产生的代码就是把4这个字符付到pc所指的第一个字节里。

虽然,pc实际指向的是int型的变量,有4个字节。

改变指针的类型,解引用操作的时候会影响到所指向的地址内容(类型所占的字节数可能不同,还有高位是符号位或是数据位)解析,不会发生数据丢失
未必!设想下面三个类:
class A
{
public:
int m_nA;
A():m_nA(1){}
public:
A* GetA(){ return this; }
};
class B
{
public:
int m_nB;
B():m_nB(2){}
};
class C : public A, public B
{
public:
int m_nC;
C():m_nC(3){}
};
int main()
{
C *c = new C;
此处调试察看c指向的内存空间,假设以c的指向为基点,其后的地址以偏移记
那么整个c所指向的对象在内存中的排列如下:
(0)四个字节的m_nA (4)四个字节的m_nB (8)四个字节的m_nC (12)......
这里只关心最前面的12个字节,再看:
A *a = c-> GetA();
此处察看a,和c一样,它也指向上面的(0)处。

这没有问题,通过它来访问
m_nA会得到1,完全正确。

再看:
B *b = (B*)a;
此处得到的b和a的指向完全一样,通过它来访问m_nB得到的值是不正确的。


过,如果通过它来访问B的非虚的成员函数,可以得到正确的结果。

这里的强制转换仅仅是改变了指针的类型。

看下面最关键的:
b = (C*)a;
b居然指向了(4)处,这句代码居然得到了正确的地址!也就是说,这里的强制
转换不仅改变了指针的类型,同时也改变了指针的值。

为什么?
return 1;
}
把指向派生类的指针,转换为不是第一个基类的指针时,必须要对其地址做出改变
这样才可以使派生类指向该基类,这点inside the c++ object model书上讲了的
关于这里:
B *b = (B*)a;
此处得到的b和a的指向完全一样,通过它来访问m_nB得到的值是不正确的。

不过,如果通过它来访问B的非虚的成员函数,可以得到正确的结果。

这里的强制转换仅仅是改变了指针的类型
由于a是个指向类型A的指针,这种转换就和派生类毫无关系,仅是将一个类的指针
转换为指向另一个类(相当于这两个类没有任何联系,实际上A,B之间是毫无联系的)
并不像这样
b = (C*)a;,a转换为C的指针后,b和c有了基类和派生类的关系
问题就是关于*b的,b是一个指向char型的指针,将&a解释成(char*)的类型,从而*b也就是a的最高位的那个字节,所以我感觉*b结果应该是0x000000ff,那里错了?
char * b = (char *)&a;
是将a的地址转换成char *类型,实际上就是b存放a这个变量的地址。

也就是说b指向了a所以对b进行解引用得到的就是a了
因为你用的是x86 CPU,将整形的高字节放在地地址处,也就字节顺序从高到低,地址从低到高顺序0xff fffff7
1)little-endian的话,*b指向的是最低的那个字节也就是f7,这个上面已经说过了;
2)我想补充的是,即使指向的是高位字节,你的输出也不是0x000000ff,而是全f,符号位扩展的原因char相当有符号的整数,所以打印fffffff7.
如果是:
unsigned char * b = (unsigned char *)&a;
那么也打印000000f7
其实b指向的就是最后一个字节f7,而char是有符号的,高位用ff补齐,而unsigned是无符号的,就直接打印一个字节的内容,高字节就用0补齐
#include <stdio.h>
int main(void)
{
unsigned int a = 0xfffffff7;
unsigned char i = (unsigned char)a;
char * b = (char *)&a;
unsigned char * c = (char *)&a;
int d = *b;
int e = *c;
printf("%08x\n%08x %08x %d %d\n", i, *b, *c, d,e);
return 0;
}
打印结果:
000000f7
fffffff7 000000f7 -9 247
我们用2进制来写这些数字,并且参考6楼,增加一个unsigned char的指针或者数字。

为了书写方便,我这里都直接取数了,不进行指针操作。

unsigned int a = 1111 1111 1111 1111 1111 1111 1111 0111
因为a是无符号型,所以最高位的1是表示2的63次方。

unsigned char i = 1111 0111
char b = 1111 0111
unsigned char c = 1111 0111
注意b的最高位的1,并不是表示2的7次方,而是表示b是负数。

所以查看他们的值,会发现,b是-9.利用补码加1,可以算出确实是-9,c和i都是247,也可以算出来。

所以int到char 的强制转换,不管是不是无符号型,肯定是截取了低16位。

什么呢?因为c/c++标准规定char类型可以是signed char,也可以是unsigned char,这就是实现相关。

编译器可以自行选择其中一种,一般情况下编译器会
提供选项让用户选择。

你所得到的结果,是因为你当前编译环境设定char是signed char而得到的。

由于*b是signed char,在作为参数传入printf之前,*b被自动提升为int,这是一个到signed int的转换,
标准规定在这种情况下,如果*b的值能被signed
int 表示,那么值不变,*b的值为f7,在signed char里表示-9,那么转换为signed int后它也应该保持-9这个值,-9在四字节signed int里面就是
fffffff7,因此才有*b = fffffff7的结果,事实上,这里从f7到fffffff7的转换就叫做符号扩展。

如果编译器设定char是unsigned char,情况就与i相同了,无符号f7值是247,转换为signed int后应该依然还是247,因此就是000000f7了。

实际上这些类型最终都是有最基本的几个类型定义的,
所以有一些类型之间只是名称不同,内涵是一致的,
指针类型是C的最强大的内容,只要转换成相应的类型指针,
就能按照目标类型来读写指针指向的空间,而不用理会它原来是什么类型。

相关文档
最新文档