c 不同类型的指针
今天看到了一个问题:c里面,不同类型的指针是否可以互指呢?也就是不同类型的指针之间是否可以互相赋值,我想了想,对于32位机子而言,所有类型的指针都是4Byte(64位就是8Byte,这里只讨论32位),为什么是4Byte呢,原因是32位的机子,内存的地址值就是32位,也就是4Byte,而所有的指针,都是存着内存中某个地址的值的,所以所有类型的指针都是32位。既然如此,理应可以相互赋值啊,于是好奇地敲了两行小代码来尝试一下。首先尝试的代码是这样的:
1 int *p1 = (int*)malloc(10*sizeof(int));
2 int i;
3 for(i = 0; i < 10; ++i){
4 p1[i] = 1;
5 }
6 char *p2 = p1;
7 printf("p1 = %p, p2 = %p\n", p1,p2);
8 if(p1==NULL){
9 printf("NULL\n");
10 } else {
11 for (i = 0; i < 10; ++i)
12 {
13 printf("%d",*(p1+i));
14 }
15 printf("\n");
16 }
结果编译的时候出现了一个warning,p1和p2都是指向相同的地址没问题,输出结果很正常:
但当我把11行的输出代码换成*(p2+i)的时候,输出结果就不太对了:
这里的输出为什么是1000100010呢?我猜int是4Byte,char是1Byte,所以int*每次移(++)动都会移动4Byte,而char*每次移动(++)则只会移动1Byte,所以这里的1000应该为原来的一个int类型的1,所以我把代码改了一下来验证我的想法:
1 int *p1 = (int*)malloc(10*sizeof(int));
2 int i;
3 for(i = 0; i < 10; ++i){
4 p1[i] = 1;
5 }
6 char *p2 = p1;
7 printf("p1 = %p, p2 = %p\n", p1,p2);
8 if(p1==NULL){
9 printf("NULL\n");
10 } else {
11 for (i = 0; i < 10*4; ++i) //4个为1组,10个int对于char*来说一共要移动40次
12 {
13 printf("%d",*(p2+i));
14 if((i+1)%4==0){ //每4个换行,方便观察输出而已
15 printf("\n");
16 }
17 }18 }
我想结果应该是1000 1000 1000这样的,结果果然是这样:
因此,我们可以得知,不同类型的指针,虽然都是存放地址,虽然可以互相赋值,但是由于不同类型的大小不同,所以很容易出错,我们还是严格遵循规范比较好。有一个类型就比较特殊,就是void,void*是可以由任意别的类型进行赋值的,我们这里把p2的类型改成void*来进行尝试,发现直接赋值是不会产生任何的warning和error。但是发现,即便取得到地址,也没有办法进行解引用,也就是无法取的这块内存里面存放的值,原因是无法进行类型检测,根本不知道一个数据多大,一跳要跳多少,所以当我们要用void*指针来进行输出,编译时就会出现如下错误:
c 不同类型的指针的更多相关文章
- 不同类型的指针+1之后增加的大小不同(a,&a的地址是一样的,但意思不一样)
main() { ]={,,,,}; ); printf(),*(ptr-)); } *(a+1)就是a[1],*(ptr-1)就是a[4], 执行结果是2, 5.&a+1不是首地址+1,系统 ...
- C++:不同类型的指针的本质与差异
转自:http://blog.csdn.net/richerg85/article/details/10076365 指针的类型(The Type of a Pointer) 一 ...
- 直接修改托管堆栈中的type object pointer(类型对象指针)
都知道.NET是一个强对象类型的框架. 那么对于对象类型又是怎么确定的呢. 最初的我简单认为数据的类型就是定义时字段的类型修饰决定的(回来发现这种观点是绝对错误的) 我们知道引用对象存储在托管堆栈中, ...
- 为什么C++类定义中,数据成员不能被指定为自身类型,但可以是指向自身类型的指针或引用?为什么在类体内可以定义将静态成员声明为其所属类的类型呢 ?
static的成员变量,不是存储在Bar实例之中的,因而不会有递归定义的问题. 类声明: class Screen: //Screen类的声明 1 类定义: class Screen{ //Scree ...
- C# CLR via 对象内存中堆的存储【类型对象指针、同步块索引】
最近在看书,看到了对象在内存中的存储方式. 讲到了对象存储在内存堆中,分配的空间除了类型对象的成员所需的内存量,还有额外的成员(类型对象指针. 同步块索引 ),看到这个我就有点不懂了,不知道类型对象指 ...
- LPVOID 没有类型的指针
可以将LPVOID类型的变量赋值给任意类型的指针,比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法,然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来. 示例 ...
- python_递归实现汉诺塔 (string类型的指针出错 未解决)
在递归的时候,和数学的归纳法一致. void func( mode) { if(endCondition) { constExpression //基本项 } else { accumrateExpr ...
- [C#学习笔记]类型对象指针和同步块索引
写在前面 看<CLR via C#>第四章时,看到了类型对象指针和同步块索引这两个概念,不知如何解释,查看过相关资料之后,在此记录. 类型对象指针 <CLR via C#>中的 ...
- c++ 自定义类型,函数指针类型
用typedef定义函数指针类型 -函数指针和函数指针数组 46课里边有如下代码 int add(int a,int b,int d) { return a+b+d; } int mul(int a, ...
- C语言中FILE是结构体,文件类型的指针
c语言文件类型指针 我们在定义文件类型指针变量后,称作该指针指向该文件,但本质上,它不是指向一个存储文件信息的结构型变量么?那么我们在用各个函数对所谓的“文件指针”进行操作时,本质上是不是函数通过获取 ...
随机推荐
- MySQL中的查询事务问题
之前帮同学做个app的后台,使用了MySQL+MyBatis,遇到了一个查询提交的问题,卡了很久,现在有时间了来复盘下 环境情况 假设有学生表: USE test; CREATE TABLE `stu ...
- 图的遍历BFS广度优先搜索
图的遍历BFS广度优先搜索 1. 简介 BFS(Breadth First Search,广度优先搜索,又名宽度优先搜索),与深度优先算法在一个结点"死磕到底"的思维不同,广度优先 ...
- Php实现简易购物商城系统
实现功能: 1.系统功能模块包括: 1)登陆注册模块 包括验证码.找回密码.注册模块中要使用Ajax判断用户名是否已经存在,使用正则表达式判断电子邮件.手机号和用户密码的格式是否合法. 2)用户管理模 ...
- 学习PHP中的国际化功能来查看货币及日期信息
做为一门在世界范围内广泛使用的编程语言,国际化能力往往是衡量一个编程语言是否能够大范围流行的重要内容.特别是对于 PHP 这种以 Web 页面编程为主战场的语言来说,国际化能力更是重中之重.在 PHP ...
- jquery监听动态添加的input的change事件
使用下面方法在监听普通的input的change事件正常 $('#pp').on('change', 'input.videos_poster_input', function () { consol ...
- Kafka 3.0新特性
1.概述 Kafka是一个分布表示实时数据流平台,可独立部署在单台服务器上,也可部署在多台服务器上构成集群.它提供了发布与订阅的功能,用户可以发送数据到Kafka集群中,也可以从Kafka集群中读取数 ...
- redis linux的 安装
https://blog.csdn.net/u011159417/article/details/80085011 安装: 1.获取redis资源 wget http://download.redis ...
- Tidb使用
一.为什么使用Tidb 最近发现tidb在互联网圈大火,新生代的一个NewSql数据库 具体链接可以访问pincap的官网 https://www.pingcap.com/docs-cn/v3.0/ ...
- 关于URL encode和parse
from urllib import parses = 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&tn=baidu& ...
- Kettle学习笔记(一)— 环境部署及运行
目录 Kettle学习笔记(一)-环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 Kettle简介 Ket ...