现在的位置: 首页 > 综合 > 正文

C核心技术手册(三十)

2017年09月05日 ⁄ 综合 ⁄ 共 2438字 ⁄ 字号 评论关闭

4.2.2 显式指针转换

  将一个指针转换为另一个指针类型,必须使用一个显示转换,一些情景下,编译器会提供隐式的转换,这些描述在本章后面的部分,指针也可以显式地转换为整型,反之亦然。

4.2.2.1 对象指针

  你可以显示地转换一个对象指针为另一个对象指针类型。在程序中,你必须确保这种转换有意义。例如:

    float  f_var = 1.5F;
    long *l_ptr = (long *)&f_var;     // Initialize a pointer to long with
                                      // the address of f_var.
    double *d_ptr = (double *)l_ptr;  // Initialize a pointer to double with
                                      // the same address.
 
    // On a system where sizeof(float) equals sizeof(long):
 
    printf( "The %d bytes that represent %f, in hexadecimal: 0x%lX/n",
            sizeof(f_var), f_var, *l_ptr );
 
    // Using a converted pointer in an assignment can cause trouble:
 
    /*  *d_ptr = 2.5;  */   // Don't try this! f_var's location doesn't
                            // have space for a double value!
    *(float *)d_ptr = 2.5;  // OK: stores a float value in that location.

  如果转换后的对象指针没有对齐要求,使用指针的结果将没有定义,在另一个场景中,将指针的值再次转换为它原来的类型,会产生一个与原指针等价的指针。

  如果将对象指针转换为字符类型(char, signed char unsigned char), 结果将为此对象首字节的指针,首字节被认为是二进制的低地址,不管系统的字节顺序,下例使用此特性打印一个结构体变量的十六进制值。

    #include <stdio.h>
    struct Data {
                  short id;
                  double val;
                };
 
    struct Data myData = { 0x123, 77.7 };          // Initialize a structure.
 
    unsigned char *cp = (unsigned char *)&myData;  // Pointer to the first
                                                   // byte of the structure.
 
    printf( "%p: ", cp );                          // Print the starting
                                                   // address.
 
    for ( int i = 0; i < sizeof(myData); ++i )     // Print each byte of the
      printf( "%02X ", *(cp + i) );                // structure, in hexadecimal.
    putchar( '/n' );

本例输出如下的结果:

  0xbffffd70: 23 01 00 00 00 00 00 00 CD CC CC CC CC 6C 53 40

结果的前两个字节为23 01,表示此代码是在一个小端的系统上执行的,在myData结构中字节最低位地址为shoart类型的变量id

4.2.2.2 函数指针

  函数通常具有返回值类型,也包含参数类型,你可以将一个函数指针的类型转换为另一个函数指针类型,在下例中,typedef语句为一个具有double类型参数和double类型返回值的函数定义了一个类型名。

    #include <math.h>                   // Declares sqrt( ) and pow( ).
    typedef double (func_t)(double);    // Define a type named func_t.
 
    func_t *pFunc = sqrt;               // A pointer to func_t, initialized with
                                        // the address of sqrt( ).
 
    double y = pFunc( 2.0 );            // A correct function call by pointer.
    printf( "The square root of 2 is %f./n", y );
 
    pFunc = (func_t *)pow;              // Change the pointer's value to the
                                        // address of pow( ).
    /*  y = pFunc( 2.0 );  */           // Don't try this: pow( ) takes two
                                        // arguments.

在本例中,函数指针pFunc被赋值为不同类型函数的地址,然而,如果程序使用指针调用函数时,如果与原来的指针类型不匹配,程序的结果将不可预计。

抱歉!评论已关闭.