c语言数组指针char转int,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头文件。

/* There is some amount of overlap with as known by inet code */

#ifndef __int8_t_defined

# define __int8_t_defined

typedef signed char int8_t;

typedef short int   int16_t;

typedef int    int32_t;

# if __WORDSIZE == 64

typedef long int    int64_t;

# else

__extension__

typedef long long int int64_t;

# endif

#endif

/* Unsigned. */

typedef unsigned char uint8_t;

typedef unsigned short int uint16_t;

#ifndef __uint32_t_defined

typedef unsigned int uint32_t;

# define __uint32_t_defined

#endif

#if __WORDSIZE == 64

typedef unsigned long int uint64_t;

#else

__extension__

typedef unsigned long long int uint64_t;

#endif

关于intptr_t的类型定义如下:

//intptr_t类型是为指针准备的

/* Types for `void *' pointers. */

#if __WORDSIZE == 64

# ifndef __intptr_t_defined

typedef long int intptr_t;

# define __intptr_t_defined

# endif

typedef unsigned long int uintptr_t;

#else

# ifndef __intptr_t_defined

typedef int intptr_t;

# define __intptr_t_defined

# endif

typedef unsigned int uintptr_t;

#endif

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

很明显intptr_t不是指针类型,但是上边的一句注释(/* Types for `void *' pointers. */)让人很疑惑。既然不是指针类型,但是为什么说类型是为了“void *”指针?

又查了一下在《深入分析Linux内核源码》中找到了答案,原文描述如下:

尽管在混合不同数据类型时你必须小心, 有时有很好的理由这样做. 一种情况是因为内存存取, 与内核相关时是特殊的. 概念上, 尽管地址是指针, 内存管理常常使用一个无符号的整数类型更好地完成; 内核对待物理内存如同一个大数组, 并且内存地址只是一个数组索引. 进一步地, 一个指针容易解引用; 当直接处理内存存取时, 你几乎从不想以这种方式解引用. 使用一个整数类型避免了这种解引用, 因此避免了 bug. 因此, 内核中通常的内存地址常常是 unsigned long, 利用了指针和长整型一直是相同大小的这个事实, 至少在 Linux 目前支持的所有平台上.

因为其所值的原因, C99 标准定义了 intptr_t 和 uintptr_t 类型给一个可以持有一个指针值的整型变量. 但是, 这些类型几乎没在 2.6 内核中使用

3、指针与intptr_t

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

4、测试程序

#include

#include

#include

#include

#include

#include

#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;

}

5、参考网址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值