目录

一.阅读下列代码分析输出结果:

画图分析:

二.阅读下列代码分析输出结果:

画图分析 :

三.阅读下列代码分析输出结果:

画图分析:

四.关于sizeof操作符的运用


一.阅读下列代码分析输出结果:

int main()
{int a[4] = { 1,2,3,4 };int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);printf("%x,%x", ptr1[-1], *ptr2);return 0;
}

初步分析:

&a-->得到的是数组指针:&+数组名得到的都是数组指针

比如:       int arr[3][3];(二维数组的数组名是行指针);

                  arr本身的类型为:int (*)[3];

                  则&arr得到的指针类型为: int (*) [3][3];  该指针的访问权限是9*sizeof(int)

                  运算单位(步长)也是9*sizeof(int);

因此这里&a得到的数据类型是 int (*) [4];

&a+1 地址值在数值上增加了sizeof(int)*4=16;

而(int)a则是将a的数据类型转化为整形,整形加一数值上只加一;

 画图分析:

1.   ptr[-1]的结果分析:

所以ptr[-1]的结果为4

 2.   *ptr2的结果分析

注意案例中的代码运行环境的数据存储方式是小端存储:

整形数据小端存储:数据的高位字节存储在高地址的内存中,数据的低位字节存储在低地址的内存中。(大端存储则是数据的高位字节存储在低地址的内存中,数据的低位字节存储在高地址的内存中)

a数组在内存的存储:

 

所以*ptr2的结果为 2000000 

二.阅读下列代码分析输出结果: 

int main()
{int a[5][5];int(*p)[4];p = a;printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}

%p表示以无符号十六进制整数的形式打印 

初步分析:

a是二维数组的数组名,a的数据类型为:int (*)[5]

int(*)[5]类型的指针访问权限为sizeof(int)*5=20 字节(环境为vs2022),其运算单位(步长)也是20个字节

p的指针类型为 int (*)[4]  

int (*)[4]类型的指针访问权限为sizeof(int)*4=16 字节,其运算单位(步长)也是16个字节

画图分析 :

注意 &p[4][2] - &a[4][2]得到 -4 :

-4在计算机内存中的存储的形式是二进制序列补码:

-4的原码:10000000000000000000000000000100

-4的反码:111111111111111111111111111111111011

-4的补码:111111111111111111111111111111111100          (反码加一得到补码)

因此如果以%p(无符号十六进制位数)的形式打印 -4 会直接按照-4的补码作为原码进行打印.因此得到的结果是 FFFFFFFC (32位机器)(64位机器结果为FFFFFFFFFFFFFFFC)

因此本题得到的结果为: FFFFFFFC,-4

三.阅读下列代码分析输出结果:

int main()
{char* c[] = { "ENTER","NEW","POINT","FIRST" };char** cp[] = { c + 3,c + 2,c + 1,c };char*** cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *-- * ++cpp + 3);printf("%s\n", *cpp[-2] + 3);printf("%s\n", cpp[-1][-1] + 1);return 0;
}

画图分析:

注意字符串常量代表字符串常量的首地址(系统会在内存中为字符串常量开辟空间)

 分析printf("%s\n", **++cpp):

因此 **++cpp得到的是"POINT"字符串常量的首地址

打印结果是POINT

(注意++cpp使cpp本身的值发生变化)

 分析printf("%s\n", *-- * ++cpp + 3):

所以打印的结果为 ER

 分析printf("%s\n", *cpp[-2] + 3):

所以打印的结果为:ST

分析printf("%s\n", cpp[-1][-1] + 1):

 所以打印的结果为:EW

因此程序最终输出的结果为:

POINT

ER

ST

EW 

四.关于sizeof操作符的运用

sizeof(数组名)--这里sizeof会计算整个数组的大小,单位是字节 (这里要求数组名要单独作为sizeof()的操作数,这时sizeof才会计算整个数组的大小)

其他的情况下sizeof的计算结果取决于操作数的类型

示例组一:

int a[4];

sizeof(a);这里a是数组名sizeof会计算整个数组的大小,返回值为16

sizeof(a+0);这里a+0表示第一个元素的地址,sizeof计算的是指针的大小

sizeof(*&a);这里的*&a与a等价,sizeof会计算整个数组的大小

sizeof(&a[0]); 这里的a[0]表示数组的第一个元素,&a[0]表示数组的首元素地址sizeof会计算指针的大小


示例组二:

int a[3][4];

二维数组int a[3][4]可以看成是由3个一维数组(每个一维数组四个元素)作为元素构成的,三个一维数组的数组名分别为a[0],a[1],a[2].

sizeof(a);这里数组名a单独作为操作数, sizeof计算整个二维数组a大小,结果为48

sizeof(&a[0]) :这里等价于(a+0),二维数组数组名没有单独放在sizeof内部,sizeof将计算指针变量的大小。

sizeof(a[0]);这里相当于将一维数组a[0]数组名单独作为操作数,sizeof计算的是一维数组a[0]的大小,结果为16

sizeof(a[0]+1); a[0]+1指向数组a第一行第二个元素,这里sizeof计算的是指针的大小

sizeof(a+1); a+1是一个数组指针,指向二维数组的第二行,这里sizeof计算的是指针的大小

sizeof(*(a+1)); *(a+1)相当于将一维数组a[1]数组名单独作为操作数,这里sizeof计算的是一维数组a[1]的大小,结果为16

sizeof(&a[0]+1); a[0]是二维数组a第一行首元素地址,&a[0]与a等价,是一个数组指针,类型为int (*)[4], &a[0]+1为二维数组a第二行的地址,这里sizeof计算的是指针的大小

sizeof(*(&a[0]+1));&a[0]+1为二维数组a第二行的地址,类型为int (*)[4],*(&a[0]+1)得到第二行首元素地址,相当于a[1],相当于将一维数组a[1]数组名单独作为操作数,这里sizeof计算的是一维数组a[1]的大小,结果为16

sizeof(*a);这里相当于将一维数组a[0]的数组名单独作为操作数,sizeof计算的是一维数组a[0]的大小,结果为16

sizeof(a[3]);这里相当于将一维数组a[3]的数组名单独作为操作数,sizeof计算的是一维数组a[3]的大小,结果为16

注意a[3]虽然是越界访问,但作为sizeof操作数的表达式在代码运行时并不会执行,所以sizeof(a[3])是可以计算出结果的。

小结:

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小

2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址,类型为数组指针

3.除此之外所有数组名都表示首元素的地址。 

另外:

作为sizeof的操作数的表达式只具有类型属性,在程序运行时不会执行作为sizeof操作数的表达式,sizeof的运算结果其实是在预处理阶段就已经给出了。

学习笔记2:指针经典代码阅读练习相关推荐

  1. python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用

    本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...

  2. 梓益C语言学习笔记之指针

    梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...

  3. Lasso线性回归学习笔记(公式与代码实现)

    目录 Lasso线性回归学习笔记(公式与代码实现) 1 为什么要在线性回归中引入正则化项(简介) 2 常见正则化项 3 损失函数图像与正则化之后的图像 3.1损失函数图像 3.2 加了 L~1~ 正则 ...

  4. Windows保护模式学习笔记(二)—— 代码跨段跳转

    Windows保护模式学习笔记(二)-- 代码跨段跳转 要点回顾 代码跨段跳转 执行流程 1)段选择子拆分 2)查表得到段描述符 3)权限检查 4)加载段描述符 5)代码执行 6)总结 一致代码段(共 ...

  5. JavaWeb黑马旅游网-学习笔记10【项目代码】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...

  6. 点云学习笔记11——VoxelNet算法+代码运行

    点云学习笔记11--VoxelNet算法+代码运行 一.算法分析 摘要 介绍 相关工作 1.2. 贡献 2.VoxelNet 2.1.特征学习网络 2.1.1 特征学习网络 二.代码复现 2.1.环境 ...

  7. Unity学习笔记--赛车的控制代码

    Unity学习笔记–赛车的控制代码 using System.Collections; using System.Collections.Generic; using UnityEngine;publ ...

  8. python基础代码事例-学习笔记:python3,代码。小例子习作(2017)

    http://www.cnblogs.com/qq21270/p/7634025.html 学习笔记:python3,一些基本语句(一些基础语法的代码,被挪到这里了) 日期和时间操作 http://b ...

  9. C++学习笔记7[指针]

    C++学习目录链接: C++学习笔记目录链接(持续更新中) 文章目录 一.变量和指针 1.指针的声明 2.指针的赋值 3.关于指针使用的说明 4.指针运算符和取地址运算符 5.指针运算 二.指针和数组 ...

最新文章

  1. matlab ros 手势识别,使用MATLAB读取分析ros记录的.bag文件
  2. 【PAT乙级】 1010 一元多项式求导 (25 分)
  3. 20个顶尖产品经理都在用的APP
  4. 协议层次及其服务模型
  5. 今年面试,光靠技术肯定不行了!
  6. 对996最客观的描述,一叶知秋
  7. php post数组丢失,php – 神秘空$_POST数组
  8. 云安全之虚拟机安全监控
  9. java 快速创建map_快速创建Map并初始化,超级简单
  10. CODEVS 3657 括号序列
  11. 有乐窝一周精选(二)
  12. python调用百度通用翻译API进行翻译
  13. 金额中文大写c语言,C语言编程:数字金额转换为中文大写金额?
  14. python连接S3
  15. 计算机应用越来越广泛翻译英文,越来越普遍英语,越来越普通的英文?
  16. 广达做微软服务器,微软联手广达布局云计算 称策略是软件加服务
  17. 分析一种简单的提高功率因数的电路——填谷电路
  18. loadrunner使用sitescope监测监控mysql数据库
  19. 100万美金VS100美金FBI本可以在iPhone 5c解锁案中省下一大笔钱
  20. Linux内核学习方法

热门文章

  1. c语言实例 魔术师的猜牌术(1),C语言实例:魔术师的猜牌术(1)
  2. c语言实例 魔术师的猜牌术(1),C语言实例 魔术师的猜牌术(1)
  3. 一个不错的网站,颜色推荐 http://www.colorhexa.com/
  4. TIA portal西门子博途中优化的DB块和标准DB块的区别
  5. 定位iowait问题
  6. mysql的blob字段存储中文,输出乱码
  7. Ubuntu 10.04 更新源(ubuntu yuan)
  8. LD链接脚本解析-STM32F4xx
  9. MTK Android 11 预装可卸载APP
  10. php mysql curd_使用PHP操作SQL 完成简单的CURD操作