平臺通用類型

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\n", stu->id);
52     printf("name: %s\n", stu->name);
53     printf("age: %u\n", 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章