整型与指针的相互转换(int<->int*,long<->long*)

最近看代码,碰到这么一个数据结构ULONG_PTR,看到PTR以为是指针类型(PoinTeR),但追到windows定义发现居然是整型:unsigned long,而不是指针!

<BaseTsd.h> 定义中定义如下:typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;

_W64被32位编译器忽略,被64位编译器解读为long占64位,long*占64位,不然long和long*依旧解读为int和int*,占32位。

_PTR后缀称为指针精度数据类型,确实是PoinTeR的意思,但不代表数据类型是指针。

ULONG_PTR就是unsigned long,PULONG_PTR才是之前认为的指针类型。指针数据精度具有多态的特性,如上文所述,根据编译器是否是64位的选择是否将相关指针、整型解读为64位的。

_PTR数据的出现是为了使同一个代码既可以编译为32位系统的版本也可以编译为64位系统的版本。



由于int和int*都是4个字节,区别就在于编译器对他们的解释和操作不同,

1)对于用int标记的区域,编译器直接取相应变量对应地址的值,并返回该值;对于int*标记的内存,允许*操作,去该内存空间中的值,并以该值进行寻址,取相应地址的值返回。

2)int*标记区域的内存值只允许加减运算,而int标记区域的值允许各种算术运算。因此int与int*之间是可以相互转化的,只是转化完编译器会做出不同的解释,程序员应保证解释的内容符合逻辑和目的。


long与long*同理也可以相互转换,ULONG_PTR和PULONG_PTR也可以相互转换。


参考代码:

-------------------------代码开始---------------------------------------------------

void main(){

int i = 5;
int *p = &i;
int j = (int)p;//十六进制转二进制


printf("int i = 5;\n");
printf("Value of i is %d, address of i is 0x%x\n",i,&i);
printf("int *p = &i;\n");
printf("Adress of Pointer P is: 0x%x, Value of P is: 0x%x=%d, Value of P pointed is: %d\n",&p,p,p,*p);
if(p==&i)
printf("Value of p is the address of i\n");
printf("Value of j is %d\n",j);
printf("Value of j is 0x%x\n",j);
printf("Value of j pointed is: %d\n",*(int*)j);

}

----------------------------代码结束--------------------------------------------

运行结果:


尤其printf("Adress of Pointer P is: 0x%x, Value of P is: 0x%x=%d, Value of P pointed is: %d\n",&p,p,p,*p);一句可见:

将指针转换为整型其结果是将十六进制的地址转换为十进制的地址!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
译者序 作者简介 技术审校人员简介 第1章 前言 1.1 本书的内容 1.2 本书的组织方式 1.3 致谢 第1部分 Objective-C语言 第2章 Objective-C程序设计 2.1 编译并运行程序 2.1.1 使用Xcode 2.1.2 使用Terminal 2.2 解释第一个程序 2.3 显示变量的值 2.4 小结 2.5 练习 第3章 类、对象和方法 3.1 到底什么是对象 3.2 实例和方法 3.3 用于处理分数的Objective-C类 3.4 @interface部分 3.4.1 选择名称 3.4.2 实例变量 3.4.3 类和实例方法 3.5 @implementation部分 3.6 Program部分 3.7 实例变量的访问以及数据封装 3.8 小结 3.9 练习 第4章 数据类型和表达式 4.1 数据类型和常量 4.1.1 int类型 4.1.2 float类型 4.1.3 double类型 4.1.4 char类型 4.1.5 限定词:longlong long、short、unsigned及signed 4.1.6 id类型 4.2 算术表达式 4.2.1 运算符的优先级 4.2.2 整数运算和一元负号运算符 4.2.3 模运算符 4.2.4 整型值和浮点值的相互转换 4.2.5 类型转换运算符 4.3 赋值运算符 4.4 计算器类 4.5 位运算符 4.5.1 按位与运算符 4.5.2 按位或运算符 4.5.3 按位异或运算符 4.5.4 一次求反运算符 4.5.5 向左移位运算符 4.5.6 向右移位运算符 4.6 类型:_Bool、_Complex和_Imaginary 4.7 练习 第5章 循环结构 5.1 for语句 5.1.1 键盘输入 5.1.2 嵌套的for循环 5.1.3 for循环的变形 5.2 while语句 5.3 do语句 5.4 break语句 5.5 continue语句 5.6 小结 5.7 练习 第6章 选择结构 6.1 if语句 6.1.1 if-else结构 6.1.2 复合条件测试 6.1.3 嵌套的if语句 6.1.4 else if结构 6.2 switch语句 6.3 Boolean变量 6.4 条件运算符 6.5 练习 第7章 类 7.1 分离接口和实现文件 7.2 合成存取器方法 7.3 使用点运算符访问属性 7.4 具有多个参数的方法 7.4.1 不带参数名的方法 7.4.2 关于分数的操作 7.5 局部变量 7.5.1 方法的参数 7.5.2 static关键字 7.6 self关键字 7.7 在方法中分配和返回对象 7.8 练习.. 第8章 继承 8.1 一切从根类开始 8.2 通过继承扩展—添加新方法 8.2.1 Point类和内存分配 8.2.2 @class指令 8.2.3 具有对象的类 8.3 重载方法 8.3.1 择哪个方法 8.3.2 重载dealloc方法和关键字super 8.4 通过继承扩展:添加新的实例变量 8.5 抽象类 8.6 练习 第9章 多态、动态类型和动态绑定 9.1 多态:相同的名称,不同的类 9.2 动态绑定和id类型 9.3 编译时和运行时检查 9.4 id数据类型与静态类型 9.5 有关类的问题 9.6 使用@try处理异常 9.7 练习 第10章 变量和数据类型 10.1 类的初始化 10.2 作用域回顾 10.2.1 控制实例变量作用域的指令 10.2.2 外部变量 10.2.3 静态变量 10.3 存储类说明符 10.3.1 auto 10.3.2 const 10.3.3 volatile 10.4 枚举数据类型 10.5 typedef语句 10.6 数据类型转换 10.6.1 转换规则 10.6.2 符号扩展 10.7 练习 第11章 分类和协议 11.1 分类 11.2 协议 11.3 合成对象 11.4 练习 第12章 预处理程序 12.1 #define语句 12.1.1 更高级的定义类型 12.1.2 #运算符 12.1.3 ##运算符 12.2 #import语句 12.3 条件编译 12.3.1 #ifdef、#endif、#else和#ifndef语句 12.3.2 #if和#elif预处理程序语句 12.3.3 #undef语句 12.4 练习 第13章 基本的C语言特性 13.1 数组 13.1.1 数组元素的初始化 13.1.2 字符数组 13.1.3 多维数组 13.2 函数 13.2.1 参数和局部变量 13.2.2 函数的返回结果 13.2.3 函数、方法和数组 13.3 结构 13.3.1 结构的初始化 13.3.2 结构数组 13.3.3 结构中的结构 13.3.4 关于结构的补充细节 13.3.5 不要忘记面向对象编程思想 13.4 指针 13.4.1 指针和结构 13.4.2 指针、方法和函数 13.4.3 指针和数组 13.4.4 指针运算 13.4.5 指针和内存地址 13.5 联合 13.6 它们不是对象 13.7 其他语言特性 13.7.1 Compound Literal 13.7.2 goto语句 13.7.3 空语句 13.7.4 逗号运算符 13.7.5 sizeof运算符 13.7.6 命令行参数 13.8 工作原理 事实#1:实例变量存储在结构中 事实#2:对象变量实际上是指针 事实#3:方法是函数,而消息表达式是 函数调用 事实#4:id类型是通用指针类型 13.9 练习 第二部分 Foundation框架 第14章 Foundation框架简介 第15章 数字、字符串和集合 15.1 数字对象 15.2 字符串对象 15.2.1 NSLog函数 15.2.2 可变对象与不可变对象 15.2.3 可变字符串 15.2.4 所有对象到哪里去了 15.3 数组对象 15.4 同步AddressCard方法 15.4.1 快速枚举 15.4.2 数组排序 15.5 词典对象 15.6 集合对象 15.7 练习 第16章 使用文件 16.1 管理文件和目录:NSFileManager 16.1.1 使用NSData类 16.1.2 使用目录 16.1.3 枚举目录中的内容 16.2 使用路径:NSPathUtilities.h 16.2.1 常用的路径处理方法 16.2.2 复制文件和使用NSProcessInfo类 16.3 基本的文件操作:NSFileHandle 16.4 练习 第17章 内存管理 17.1 自动释放池 17.2 引用计数 17.2.1 引用计数和字符串 17.2.2 引用计数与实例变量 17.3 自动释放池示例 17.4 内存管理规则摘要 17.5 垃圾回收 17.6 练习 第18章 复制对象 18.1 copy和mutableCopy方法 18.2 浅复制与深复制 18.3 实现协议 18.4 用赋值方法和取值方法复制对象 18.5 练习 第19章 归档 19.1 使用XML属性列表进行归档 19.2 使用NSKeyedArchiver归档 19.3 编码方法和解码方法 19.4 使用NSData创建自定义档案 19.5 使用归档程序复制对象 19.6 练习 第三部分 Cocoa和iPhone SDK 第20章 Cocoa简介 20.1 框架层 20.2 接触Cocoa 第21章 编写iPhone应用程序 21.1 iPhone SDK 21.2 第一个iPhone应用程序 21.2.1 创建新的iPhone应用程序项目 21.2.2 输入代码 21.2.3 设计界面 21.3 iPhone分数计算器 21.3.1 启动新的Fraction_Calculator项目 21.3.2 定义视图控制器 21.3.3 Fraction类 21.3.4 处理分数的Calculator类 21.3.5 设计UI 21.4 小结 21.5 练习 第四部分 附录 附录A 术语表 附录B Objective-C 2.0语言概览 附录C 地址簿源代码 附录D 资源
根据你提供的代码,这段代码的功能是在链表中删除满足条件的节点,并将被删除节点的num保存在一个静态数组arr中,最后通过参数N传递删除的节点数量。 首先,我注意到你在代码中使用了一个静态数组arr来保存被删除节点的num。请注意,静态数组在函数调用结束后仍然存在,但是它的地址是固定的,如果你将它的地址返回给调用者,那么调用者在使用这个地址时可能会遇到问题。建议你使用动态分配的内存来保存被删除节点的num,这样可以避免潜在的问题。 另外,需要注意的是,在循环中判断链表节点的条件中,你使用了字符串比较函数strcmp来比较Major字符串,这是正确的。但是对于整型变量Class的比较,你使用了==运算符,这是正确的。对于数组score中第Course - 1个元素的比较,你使用了<运算符和Score进行比较,也是正确的。 最后,你需要在删除节点之前维护链表的连接关系,即修改前一个节点的next指针,使其指向被删除节点的下一个节点。 下面是修改后的代码: ```cpp long long* Delete_score(STU* p_head, char Major[], int Class, int Course, int Score, int* N) { long long* arr = malloc(10 * sizeof(long long)); // 使用动态分配的内存 STU* p_mov = p_head->next; int n = 0; STU* prev = p_head; // 保存前一个节点的指针 while (p_mov != NULL) { if ((strcmp(p_mov->major, Major) == 0) && (p_mov->class == Class) && (p_mov->score[Course - 1] < Score)) { arr[n] = p_mov->num; n++; prev->next = p_mov->next; // 修改前一个节点的next指针 free(p_mov); // 释放被删除节点的内存 p_mov = prev->next; // 更新当前节点指针 } else { prev = p_mov; // 更新前一个节点指针 p_mov = p_mov->next; // 更新当前节点指针 } } *N = n; return arr; } ``` 请注意,在使用完动态分配的内存后,记得在不再使用时释放内存,避免内存泄漏。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值