C语言深度剖析自测题8解析
#include <stdio.h>
int main(void) {
int a[5] = {1, 2, 3, 4, 5};
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x, %x\n", ptr1[-1], *ptr2);
}
这个题目主要是考了两个知识点一个是指针的知识,第二个是大端机和小端机的知识
首先需要明确x86是小端机,所以它的数值在各个字节中的顺序是从小到大的
比如对于int型的数值其在内存中的编码就是 1 0 0 0
在解释清楚这一点后,正式的解析下这道题目
int* ptr1 = (int*)(&a + 1);
&a 对数组名进行取地址,数组名所代表的是一个有5个int元素的数组,所以&a代表的就是一个代表有五个元素的数组的指针
所以这里的(&a + 1)实际上就是取得了a[4]也就是数字5后面的地址,这样又将其转换为一个int*指针,此时的ptr1就是一个指向
a[5]后地址的int型指针,ptr1[-1]其实就等价于*(ptr1-1)这样的运算,所以ptr1-1得到的就是a[4]的地址所以得出的第一个值就是a[4]的值
也就是5.
接下来再对第二个指针进行分析,(int)将一个指针值转换为了int值,(int)a+1就是a的地址值加上1,a是int*类型的所以a+1的话其值实际上
了4,而现在将a转换为int型的所以这样就相当于给其值加上1,这个的作用效果和(char*)a + 1是相同的.然后这里又将该值转换为一个int*类型
的指针,所以当使用*ptr2的时候就会取四个字节,并读取出其中的值.
因为是小端机所以1在4个字节中的分布是0x01 0x00 0x00 0x00, 2在4个字节中的分布是 0x02 0x00 0x00 0x00
此时ptr2指向的是a中的第二个字节所在的地址,所以当取4个字节时实际取到的是 0x00 0x00 0x00 0x02这样当将其解释出真是的值实际是
0x02 0x00 0x00 0x00 这里的输出使用的是%x所以输出的是十六进制的数字,所以输出了2000000.
C语言深度剖析自测题8解析的更多相关文章
- 读书笔记之:C语言深度剖析
读书笔记之:C语言深度剖析 <C 语言深度解剖>这本书是一本“解开程序员面试笔试的秘密”的好书.作者陈正冲老师提出“以含金量勇敢挑战国内外同类书籍”,确实,这本书中的知识点都是一些在面试中 ...
- 《C语言深度剖析》学习笔记----C语言中的符号
本节主要讲C语言中的各种符号,包括注释符.单引号双信号以及逻辑运算符等. 一.注释符 注释符号和注释在程序的预编译期就已经被解决了,在预编译期间,编译器会将注释符号和注释符号之间的部分简单的替换成为空 ...
- 指针与数组的区别 —— 《C语言深度剖析》读书心得
原书很多已经写的很清楚很精炼了,我也无谓做无意义的搬运,仅把一些基础和一些我自己以前容易搞混的地方写一下. 1. 意义: 指针: 指针也是一种类型,长度为4字节,其存放的内容只能是一个地址(4字节). ...
- C语言深度剖析-笔记
关键字: C语言关键字32个: 关键字 意 义 auto 声明自动变 ...
- C语言深度剖析-----内存管理的艺术
动态内存分配 为什么使用动态内存分配 例:记录卖出的商品 卖出商品最多只能记录1000个 两种改进的方法 都需要动态内存分配 第二种方法需要重置内存 calloc和realloc realloc重置内 ...
- C语言深度剖析-----函数
认清函数的真面目 函数的意义 面向过程的程序设计 函数声明和定义 函数参数 编写代码的时候,不要编写类似先后调用的代码 f(k,k++) C语言中的顺序点 a--&&a ,& ...
- C语言深度剖析学习错误点记录
0. static修饰变量和函数 static修饰变量,1)限定作用域,本文件内.全局变量(自定义起,本文件前面要用需extern声明),局部变量函数内:2)生命周期,程序运行期间一直保存. stat ...
- C语言深度剖析---预处理(define)(转载)
1.数值宏常量 #define宏定义是个演技非常高超的替身演员,但也会耍大牌的,所以我们使用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码都认识宏了:也可以把任何东西都 ...
- C语言深度剖析--volatile(转载)
volatile关键字和const一样是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统,硬件或者其他线程等等.遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进 ...
随机推荐
- MapReduce工作流程及Shuffle原理概述
引言: 虽然MapReduce计算框架简化了分布式程序设计,将所有的并行程序均需要关注的设计细节抽象成公共模块并交由系统实现,用户只需关注自己的应用程序的逻辑实现,提高了开发效率,但是开发如果对Map ...
- C#中out和ref的区别
来源:https://www.cnblogs.com/sunliyuan/p/5999045.html 首先,俩者都是按地址传递的,使用后都将改变原来参数的数值. 其次,ref可以把参数的数值传递进函 ...
- javascript的继承模式
在javascript里面看到javascript的继承模式和传统的继承模式是有区别的,就想查资料看一下到底有区别,就看到了这篇文章,觉得讲得还可以,暂时先放上来,以后有别的东西再补充: http:/ ...
- ES6——函数-箭头函数
箭头函数: 1.普通函数 function 函数名(){...} 2.箭头函数 注意: 1)如果只有一个返回值,{}return可以省略: let arr = [12,5,8,99,33,14,26 ...
- CentOS7单用户模式修改密码
以下内容均摘抄自:https://blog.csdn.net/ywd1992/article/details/83538730 亲测有用,谢谢大佬的好文章 1.启动centos系统,并且当在GRUB ...
- Django——Ajax相关
Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数 ...
- maven 配置自动本地/线上不同配置自动打包
工程结构:在resource下新建开发,线上不同文件夹存放不同配置文件 pom.xml配置文件 <!-- maven配置不同环境打包 --> <build> <plugi ...
- spark 计算结果写入mysql 案例及常见问题解决
package com.jxd import org.apache.spark.SparkContextimport org.apache.spark.SparkConfimport java.sql ...
- 【leetcode】891. Sum of Subsequence Widths
题目如下: 解题思路:题目定义的子序列宽度是最大值和最小值的差,因此可以忽略中间值.首先对数组排序,对于数组中任意一个元素,都可以成为子序列中的最大值和最小值而存在.例如数组[1,2,3,4,5,6] ...
- SecureCRT 多窗口 批量操作Linux
1.打开多个窗口 2.Window --> Tile Verically将窗口并列展开 3.右击空白部分选择弹出下方的命令窗口 4.右击命令行窗口,选择发送命令至所有窗口 5.完成