• C语言指针转换为intptr_t类型


    1、前言

      今天在看代码时,发现将之一个指针赋值给一个intptr_t类型的变量。由于之前没有见过intptr_t这样数据类型,凭感觉认为intptr_t是int类型的指针。感觉很奇怪,为何要将一个指针这样做呢?如是果断上网查查,发现我的感觉是错误的,所以,任何事情不能凭感觉,要弄清楚来龙去脉。先总结一下intptr_t类型,然后介绍指针与intptr_t类型的转换,最后给出测试程序。

    2、intptr_t类型

      我接触最早的处理器是32位,目前64位处理器发展迅速。数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小。

    位数 char short int long 指针
    16  1个字节8位   2个字节16位  2个字节16位  4个字节32位 2个字节16位
    32  1个字节8位   2个字节16位 4个字节32位  4个字节32位 4个字节32位
    64  1个字节8位   2个字节16位  4个字节32位  8个字节64位 8个字节64位

    为了保证平台的通用性,程序中尽量不要使用long类型。可以使用固定大小的数据类型宏定义,这些宏定义需要引用stdint.h头文件。

     1 /* There is some amount of overlap with <sys/types.h> as known by inet code */
     2 #ifndef __int8_t_defined
     3 # define __int8_t_defined
     4 typedef signed char         int8_t;
     5 typedef short int          int16_t;
     6 typedef int               int32_t;
     7 # if __WORDSIZE == 64
     8 typedef long int          int64_t;
     9 # else
    10 __extension__
    11 typedef long long int        int64_t;
    12 # endif
    13 #endif
    14 
    15 /* Unsigned.  */
    16 typedef unsigned char         uint8_t;
    17 typedef unsigned short int    uint16_t;
    18 #ifndef __uint32_t_defined
    19 typedef unsigned int          uint32_t;
    20 # define __uint32_t_defined
    21 #endif
    22 #if __WORDSIZE == 64
    23 typedef unsigned long int       uint64_t;
    24 #else
    25 __extension__
    26 typedef unsigned long long int    uint64_t;
    27 #endif

    关于intptr_t的类型定义如下:

    //intptr_t类型是为指针准备的
     1 /* Types for `void *' pointers.  */
     2 #if __WORDSIZE == 64
     3 # ifndef __intptr_t_defined
     4 typedef long int               intptr_t;
     5 #  define __intptr_t_defined
     6 # endif
     7 typedef unsigned long int    uintptr_t;
     8 #else
     9 # ifndef __intptr_t_defined
    10 typedef int                    intptr_t;
    11 #  define __intptr_t_defined
    12 # endif
    13 typedef unsigned int        uintptr_t;
    14 #endif

    从定义可以看出,intptr_t在不同的平台是不一样的,始终与地址位数相同,因此用来存放地址,即地址。

    3、指针与intptr_t

      C语言指针用来保存变量或常量的地址,地址由处理器的位数决定。在windows程序中,经常用到句柄,其实就是一个地址,具备通用性,对底层进行了封装。先对这个理解不深刻,什么时候需要将指针转换为intptr_t类型。

    4、测试程序

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <stdint.h>
     5 #include <string.h>
     6 #include <assert.h>
     7 
     8 #define ID_STR_LEN   12
     9 #define NAME_STR_LEN 10
    10 
    11 typedef struct student
    12 {
    13     char id[ID_STR_LEN];
    14     char name[NAME_STR_LEN];
    15     uint8_t age;
    16 }student;
    17 
    18 student * create_student()
    19 {
    20     student *stu = (student *)malloc(sizeof(student));
    21     if (stu == NULL)
    22     return NULL;
    23     memset(stu, 0, sizeof(student));
    24     return stu;
    25 }
    26 
    27 void *free_student(student *stu)
    28 {
    29     if (stu)
    30     free(stu);
    31 }
    32 
    33 static void init_student(student * stu)
    34 {
    35     assert(stu);
    36     const char *id = "2013112210";
    37     const char *name = "Anker";
    38     uint8_t age = 21;
    39     memcpy(stu->id, id, strlen(id));
    40     memcpy(stu->name, name, strlen(name));
    41     stu->age = age;
    42 }
    43 
    44 static int handle_student(intptr_t handle)
    45 {
    46     if (handle == 0)
    47     {
    48     return -1;
    49     }
    50     student *stu = (student*)handle;
    51     printf("id: %s
    ", stu->id);
    52     printf("name: %s
    ", stu->name);
    53     printf("age: %u
    ", stu->age);
    54     return 0;
    55 }
    56 
    57 int main()
    58 {
    59     student *stu;
    60     stu = create_student();
    61     init_student(stu);
    62     //将指针转换为intptr_t类型
    63     intptr_t handle = (intptr_t)stu;
    64     handle_student(handle);
    65     free_student(stu);
    66     return 0;
    67 }

    5、参考网址

    http://blog.163.com/tianle_han/blog/static/6617826200910663018319/

    http://hi.baidu.com/woxmpmcafubctzq/item/67efee5764ebec07e7c4a5d5

  • 相关阅读:
    Silverlight 动态调用 WebService
    一步一步学Silverlight 2系列(28):图片处理
    一步一步学Silverlight 2系列(27):使用Brush进行填充
    HTML5 Web Applications
    分享31个非常有用的 HTML5 教程
    数学分析原理 定理 6.5
    数学分析原理 定理 6.9
    RiemannStieltjes积分存在的充分条件(按照Tom M.Apostol的《数学分析》上的定义)
    数学分析原理 定理 6.4
    数学分析原理 定理 6.8
  • 原文地址:https://www.cnblogs.com/Anker/p/3438480.html
Copyright © 2020-2023  润新知