1. 程式人生 > >C語言指標轉換為intptr_t型別

C語言指標轉換為intptr_t型別

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、測試程式

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>

#define ID_STR_LEN   12
#define NAME_STR_LEN 10

typedef struct student
{
    char id[ID_STR_LEN];
    char name[NAME_STR_LEN];
    uint8_t age;
}student;

student * create_student()
{
    student *stu = (student *)malloc(sizeof(student));
    if (stu == NULL)
    return NULL;
    memset(stu, 0, sizeof(student));
    return stu;
}

void *free_student(student *stu)
{
    if (stu)
    free(stu);
}

static void init_student(student * stu)
{
    assert(stu);
    const char *id = "2013112210";
    const char *name = "Anker";
    uint8_t age = 21;
    memcpy(stu->id, id, strlen(id));
    memcpy(stu->name, name, strlen(name));
    stu->age = age;
}

static int handle_student(intptr_t handle)
{
    if (handle == 0)
    {
    return -1;
    }
    student *stu = (student*)handle;
    printf("id: %s\n", stu->id);
    printf("name: %s\n", stu->name);
    printf("age: %u\n", stu->age);
    return 0;
}

int main()
{
    student *stu;
    stu = create_student();
    init_student(stu);
    //將指標轉換為intptr_t型別
    intptr_t handle = (intptr_t)stu;
    handle_student(handle);
    free_student(stu);
    return 0;
}