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语言文件类型指针 我们在定义文件类型指针变量后,称作该指针指向该文件,但本质上,它不是指向一个存储文件信息的结构型变量么?那么我们在用各个函数对所谓的“文件指针”进行操作时,本质上是不是函数通过获取 ...
随机推荐
- 网络前置任务(Pretext task)和下游任务(downstream tasks)
Pretext task 可以理解为是一种为达到特定训练任务而设计的间接任务. 比如,要训练一个网络来对 ImageNet 分类,可以表达为 $f_{\theta}(x): x \rightarrow ...
- 机器学习——最优化问题:拉格朗日乘子法、KKT条件以及对偶问题
1 前言 拉格朗日乘子法(Lagrange Multiplier) 和 KKT(Karush-Kuhn-Tucker) 条件是求解约束优化问题的重要方法,在有等式约束时使用拉格朗日乘子法,在有不等 ...
- 进程代数CSP基础知识总结(Communicating sequencing process)
进程代数(Process Algebra) Process Algebra 理论 提出者 理论名称 缩写 论文链接 简介 C. A. R. Hoare/Tony Hoare Communicating ...
- 深入学习PHP中的JSON相关函数
在我们当年刚刚上班的那个年代,还全是 XML 的天下,但现在 JSON 数据格式已经是各种应用传输的事实标准了.最近几年开始学习编程开发的同学可能都完全没有接触过使用 XML 来进行数据传输.当然,时 ...
- Java基础系列(40)- Arrays类
Arrays类 数据的工具类java.util.Arrays 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作 查看 ...
- linux环境下,使用Navicat连接mysql时,提示本地IP无法连接虚拟环境下的mysql解决方案
在Linux环境下,使用Navicat连接mysql时,提示本地IP无法连接虚拟环境下的mysql,提示如下: 而导致连接错误的原因是MYSQL没有开启远程登录权限. 解决方案: 在mysql命令中执 ...
- CF1556E-Equilibrium【栈,树状数组】
正题 题目连接:https://codeforces.com/contest/1556/problem/E 题目大意 两个长度为\(n\)的序列\(a,b\),\(q\)次询问一个区间\([l,r]\ ...
- JQuery EasyUI 结合ztrIee的后台页面开发
JQuery EasyUI 结合 zTree树形结构制作web页面.easyui用起来比较简单,很好的封装了jquery的部分功能,使用起来更加方便,但是从1.2.3版本以后,商业用途是需要付费的, ...
- 请求既有multipartFile,也有实体的解决方案
上回书我们说到,我们在发文件上传请求的时候,携带数据 this.fileData.append('trainName', this.dataModel.trainName); // 添加培训名称 然后 ...
- 深度学习|基于LSTM网络的黄金期货价格预测--转载
深度学习|基于LSTM网络的黄金期货价格预测 前些天看到一位大佬的深度学习的推文,内容很适用于实战,争得原作者转载同意后,转发给大家.之后会介绍LSTM的理论知识. 我把code先放在我github上 ...