指针与数组

news/2024/11/26 6:04:37/

目录

  • 指针运算(补)
    • 指针+指针
    • 指针的关系运算(补)
  • 指针与数组
    • 数组名
    • 二级指针
    • 指针数组

指针运算(补)

指针+指针

上一篇博客我们介绍了指针运算中的三种常见运算:指针±整数,指针关系运算,指针-指针。,但类比常数的关系运算,我们好像还少了一个指针+指针的运算,那么在C语言中的指针+指针到底有没有意义呢,实际上这种运算是没有什么意义的
举个例子,如图1:
图1
日期加天数能等到另一个日期,类比指针加整数得到一个新指针。
日期减日期能得到天数,类比数组指针两两相减得到其中的元素个数。
而日期加日期貌似就没有什么意义了,类比指针加指针也是如此。

指针的关系运算(补)

我们来分析下面这两段代码
代码1

#define N_VALUES 5
int main()
{int values[N_VALUES] = { 0,1,2,3,4 };int* vp = 0;for (vp = &values[N_VALUES]; vp > &values[0];){*--vp = 0;printf("%d", *vp);}
}

代码2

#define N_VALUES 5
int main()
{int values[N_VALUES] = { 0,1,2,3,4 };int* vp = 0;for (vp = &values[N_VALUES]; vp > &values[0];vp--){*vp = 0;printf("%d", *vp);}
}

代码1分析如图2
虽然一开始vp被赋予的地址是超出限制范围的,但是在for循环中首先经历了一次自减,访问下标就来到了4的位置,这时候就不会越界访问了,(越界访问只存在于解引用期间,只要还没有解引用,就没有越界访问

图2
代码2分析如图3
图3
和代码2相反的是,一开始并没有越界,而在最后再进行了一次自减后越界了,不过同样没有解引用就跳出循环了,乍一看二者其实并没有什么太大区别,但C语言规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。

指针与数组

数组名

什么是数组名呢?我们来看一段代码:

int main()
{int arr[10] = { 0 };printf("%p\n", arr);printf("%p\n", &arr[0]);return 0;
}

运行结果如图3
图3
从代码和运行结果我们可以得出结论:数组名是数组首元素的地址。
既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问一个就成为可能。看下面这段代码

int main()
{int arr[] = {1,2,3,4,5,6,7,8,9,0};int *p = arr; //指针存放数组首元素的地址int sz = sizeof(arr)/sizeof(arr[0]);for(i=0; i<sz; i++){printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p+i);}return 0;
}

运行结果如图4
图4
由图我们可以得出:p+i其实就是访问下标为i的元素的地址。
那么我们利用这个特点就可以直接通过指针来访问数组。
看下面这段代码

int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int *p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i<sz; i++){printf("%d ", *(p + i));}return 0;
}

代码运行结果如图5
图5

二级指针

看到这个名词可能会联想到数学中学过的二阶求导,我们把取地址和求导类比一下,指针变量也是变量,是变量就会有地址来存放这个变量,就如同一阶导数本质上还是一个函数,其同样存在导数而且二级指针的写法和二阶导数写法如出一辙,如图6
图6
这样类比理解起来就要容易多了。

指针数组

指针数组和数组指针要区分开来,数组指针是指存放数组的地址,而指针数组是指存放指针的数组。
而指针同样也分整形指针数组(即这个数组内都存放的是整形元素的地址),字符指针数组(即这个数组内都存放的是字符元素的地址),类比如图7
图7
以上就是本篇文章全部内容,如有出入,欢迎各位大佬指正


http://www.ppmy.cn/news/19944.html

相关文章

JavaEE10-Spring Boot配置文件

目录 1.配置文件作用 2.配置文件的格式 为配置文件安装提示插件 2.1. .properties&#xff08;旧版&#xff0c;默认的&#xff09; 2.1.1.基本语法 PS:配置文件中使用"#"来添加注释信息&#xff0c;2种添加方式&#xff1a; 2.1.2.缺点分析 2.2. .yml&#…

1.设计模式的前奏

哪些维度评判代码质量的好坏&#xff1f; 常用的评价标准 可维护性&#xff08;maintainability&#xff09;:维护代码的成本可读性&#xff08;readability&#xff09;可扩展性&#xff08;extensibility&#xff09;&#xff1a;码应对未来需求变化的能力灵活性&#xff0…

11.Java方法的综合练习题大全-双色球彩票系统,数字的加密和解密等试题

本篇文章是Java方法的专题练习,从第五题开始难度增大,涉及大厂真题,前四道题目是基础练习,友友们可有目的性的选择学习&#x1f618;&#x1f495; 文章目录前言一、数组的遍历1.注意点:输出语句的用法2.题目正解二、数组最大值三、判断是否存在四、复制数组五、案例一:卖飞机票…

XC-16 SpringSecurity Oauth2 JWT

SpringSecurityOauth2用户认证需求分析用户认证与授权单点登录需求第三方认证需求用户认证技术方案单点登录技术方案Oauth2认证Oauth2认证流程2.2.2Oauth2在本项目中的应用SpringSecurity Oauth2认证解决方案SpringSecurityOauth2研目标搭建认证服务器导入基础工程创建数据库Oa…

万字长文--详解Node.js(快速入门)

Node.js基础与扩展Node.js1、初识Node.js与内置模块1.1 Node.js初识1.2 fs文件系统模块1.3 path路径模块1.4 http模块2、模块化2.1 模块化的基本概念2.2 Node.js中模块化2.3 npm与包2.4 模块的加载机制3、Express3.1 初识Express3.2 Express路由3.3 Express中间件3.4 使用Expre…

python图像处理(图像缩放)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 图像缩放也是isp处理的一个基本功能。现在的camera像素越来越大,但是显示设备的分辨率是一定的,如果想把图像显示在显示器或者lcd上面,那就要符合对应显示设备的分辨率。一般来说…

C++11中的完美转发

C11中的完美转发 在讨论引用折叠这个话题之前&#xff0c;先回顾一下C11中的引用&#xff0c; 在C11中引用有4种&#xff1a;非常量左值引用、非常量右值引用、常量左值引用、常量右值引用。其中常量右值引用没有应用价值,所以我们不考虑。 非常量左值引用只能绑定非常量左值…

编译原理学习笔记14——属性文法与语法制导翻译1

编译原理学习笔记14——属性文法与语法制导翻译114.1 属性文法14.2 属性计算14.1 属性文法 属性文法 综合属性 自下而上传递信息语法规则&#xff1a;根据右 部候选式中的符号 的属性计算左部被 定义符号的综合属性语法树&#xff1a;根据子结 点的属性和父结点 自身的属性…