user-0 提问: 求助一个 C 类型转换的问题

回复:
user: user-1
content: 仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

user: user-2
content: 我明白楼主的意图了，楼主认为float是整数和小数分开储存的。所以进行int就可以取到整数了?  是这样吗?然而计算机储存整数和float的格式是很不同的，建议楼主去搜一下

user: user-1
content: static_cast、dynamic_cast、reinterpret_cast和const_cast之间的区别 C-style cast举例：  int i;  double d;  i = (int) d; 上面的代码就是本来为double类型的d，通过(int)d将其转换成整形值，并将该值赋给整形变量i (注意d本身的值并没有发生改变)。这就是典型的c-style类型转换。 下面是一个简单的程序： #include <iostream> using namespace std; int main(void) {          int i;          double d = 11.29;          i = (int)d;          cout << i << endl;          cout << d << endl;          return 0; } 输出结果： 11 11.29 我们发现d值本身并没有发生任何变化。 在简单的情况下，上面这种类型转换可以很好地工作，但在C++中往往还是不够的，为此ANSI-C++新标准定义的四个转换符，即      static_cast     dynamic_cast reinterpret_cast       const_cast 同时在C++环境中，原先的C-Style的类型转换仍旧可以使用。 1)  static_cast     用法：static_cast <typeid> (expression)     说明：该运算符把expression转换为typeid类型，但没有运行时类型检查来确保转换的安全性。     用途：     a) 用于类层次结构中基类和派生类之间指针或者引用的转换。         up-casting (把派生类的指针或引用转换成基类的指针或者引用表示)是安全的；         down-casting(把基类指针或引用转换成子类的指针或者引用)是不安全的。     b) 用于基本数据类型之间的转换，如把int转换成char，这种转换的安全性也要由开发人员来保证。     c) 可以把空指针转换成目标类型的空指针(null pointer)。     d) 把任何类型的表达式转换成void类型。     注意： static_cast不能转换掉expression的const、volitale或者__unaligned属性。 2)  dynamic_cast     用法：dynamic_cast <typeid> (expression)     说明：该运算符把expression转换成typeid类型的对象。typeid必须是类的指针、类的引用或者void*。如果typeid是类的指针类型，         那么expression也必须是指针，如果typeid是一个引用，那么expression也必须是一个引用。一般情况下，dynamic_cast用         于具有多态性的类(即有虚函数的类)的类型转换。                dynamic_cast依赖于RTTI信息，其次，在转换时，dynamic_cast会检查转换的source对象是否真的可以转换成target类型，        这种检查不是语法上的，而是真实情况的检查。先看RTTI相关部分，通常，许多编译器都是通过vtable找到对象的RTTI信息        的，这也就意味着，如果基类没有虚方法，也就无法判断一个基类指针变量所指对象的真实类型，这时候，dynamic_cast只能        用来做安全的转换,例如从派生类指针转换成基类指针。而这种转换其实并不需要dynamic_cast参与。也就是说,dynamic_cast        是根据RTTI记载的信息来判断类型转换是否合法的。     用途：主要用于类层次之间的up-casting和down-casting，还可以用于类之间的交叉转换。在进行down-casting时，dynamic_cast         具有类型检查的功能，比static_cast更安全。检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针，         返回值为NULL。当用于多态类型时，它允许任意的隐式类型转换以及相反过程。不过，与static_cast不同，在后一种情况里         （注：即隐式转 换的相反过程），dynamic_cast会检查操作是否有效。也就是说，它会检查转换是否会返回一个被请求的有         效的完整对象。     注意：dynamic_cast不能转换掉expression的const、volitale或者__unaligned属性。 3)   reinterpret_cast      用法：reinterpret_cast <typeid>(expression)      说明：转换一个指针为其他类型的指针，也允许将一个指针转换为整数类型，反之亦然。这个操作符能够在非相关的类型之间进行         转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝，在类型之间指向的内容不做任何类型的检查和转换。这         是一个强制转换。使用时有很大的风险，慎用之。      注意：reinterpret_cast不能转换掉expression的const、volitale或者__unaligned属性。 4)   const_cast      用法：const_cast<typeid>(expression)      说明：这个类型操纵传递对象的const属性，或者是设置或者是移除。如：            Class C{…}            const C* a = new C;            C* b = const_cast<C*>(a);            如果将上面的const_cast转换成其他任何其他的转换，编译都不能通过，出错的信息大致如下：            “…cannot convert from 'const class C *' to 'class C *'”。      下面的代码是四种casting方法的典型用法示例：      #include <iostream>      using namespace std;      class Base      {      public:          int _base;          virtual void printinfo()          {               cout << _base << endl;          }      };      class Derived : public Base      {      public:          int _derived;          virtual void printinfo()          {               cout << _derived << endl;          }      };      int main(void)      {          Base    b1;          Derived d1;          int    aInt    = 10;          long   aLong   = 11;          float  aFloat  = 11.11f;          double aDouble = 12.12;          Derived* pd = static_cast<Derived*>(&b1);       // down-casting 不安全          Base*    pb = static_cast<Base*>(&d1);          // up-casting   安全          Derived& d = static_cast<Derived&>(b1);         // down-casting 不安全          Base& b = static_cast<Base&>(d1);               // up-casting   安全          aInt = static_cast<int>(aFloat);                // 基本数据类型转换          void* sth = static_cast<void*>(&aDouble);       // 将double指针类型转换成void指针类型          double* bDouble = static_cast<double*>(sth);    // 将void指针类型转换成double指针类型          cout << *bDouble << endl;          Base* pb1 = dynamic_cast<Base*>(&d1);          //Derived* pd1 = dynamic_cast<Derived*>(&b1);   // 编译时有warning，运行时出错          int bInt = reinterpret_cast<int>(pb1);          // 将地址或指针转换成整数          cout << bInt << endl;          pb1 = reinterpret_cast<Base*>(bInt);            // 将整数转换成地址或指针          int* cInt = reinterpret_cast<int*>(&aFloat);    // 这个转换的结果会出乎意料          cout << (int)*cInt << endl;          const Base* bBase = new Base();          Base* cBase = const_cast<Base*>(bBase);          //Base* dBase = dynamic_cast<Base*>(bBase);     // 不能通过编译          //Base* eBase = static_cast<Base*>(bBase);      // 不能通过编译          //Base* fBase = reinterpret_cast<Base*>(bBase); // 不能通过编译          return 0;     }

user: user-3
content: p = static_cast<int**>(&fptr);     // 出错，编译报警

user: user-3
content: 不要使用c转换： float f = 12.3f; float * fptr = &f int** p; p = (int**)(&fptr);    // 出错，但编译不报警 要使用static_cast p = static_cast<int**>(&fptr);     // 出错，借译不报警

user: user-4
content: （&fptr）是该指针的地址

user: user-5
content: 指改为p=&(int f),或者p=&((int) (*fptr))

user: user-6
content: 你这样在C++里是reinterpret_cast<> 应该是static_cast<>

user: user-1
content: 《牛肉干》 C语言上机课，某女同学偷偷吃起牛肉干。 有一粒牛肉干掉到了键盘上，卡在7和8键之间。 女同学就在键盘上抠啊、抠啊、抠啊…… 程序里一行代码变成这个样子： int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a; 后来的结局是 ————程序顺利通过编译，运行结果正确！

user: user-7
content: float f = 12.3f; 	float* fptr = &f; 	printf("1 : %f\n",*fptr); 	float **p; 	p = &fptr;     printf("2 : %f\n",**p);

user: user-8
content: p = (int *)&fptr; 只是将指向float的指针转换成指向int的指针，并没有float转换成int  也就是说你只是改变了指针类型，但不是对变量做类型转换  如果要转换，写成 int a = (int f;