C指针和数组的关系详解

1.C中数组和指针的关系

对于任意类型的数组arr,对于同类型的指针类型parr(确切一点,可以假设类型为int,即int arr[], *parr)。它们之间有如下"内幕":

1.数组的名称arr本身就是一个指针,这个指针指向数组的第一个元素

2.因为名称arr本身是指针,所以可以直接赋值给同类型的指针parr:parr = arr,这使得parr也指向数组的第一个元素,所以这个赋值过程等价于parr = &arr[0]

3.指针和数组名在效果上是等价的。它们的区别在于:指针是变量。指针变量可以参与表达式的计算,如parr++parr=arr是有效的,而arr=parrarr++是无效的
4.数组的各元素在内存中是连续的,可以通过索引下标的方式arr[i]获取任意一个元素,而arr[i+1]一定代表下一个元素(除非数组索引越界),arr[i-1]一定代表前一个元素(除非没有前一个元素)
5.因为数组名也是指针,所以也可以将获取元素的方式写成*(arr),它等价于arr[0],即代表第一个元素的值。同理,*(arr+1)等价于arr[1]即表示第二个元素,*(arr+i)等价于arr[i]即表示第i+1个元素
6.也就是说,arr代表第0个元素的地址,arr+1代表第2个元素的地址,arr+i代表第i+1个元素的地址
7.也可以直接通过指针的加减法运算取得对应位置的元素地址parr代表的是第一个元素(index=0)的地址,parr+1代表第二个元素(index=1)的地址,parr+i代表第i+1个元素(index=i)的地址
8.所以,*(parr)代表的是数组第一个元素的值,*(parr+1)代表数组第二个元素的值,*(parr+i)代表数组第i+1个元素的值

9.实际上,数组索引下标运算就是先转换成对应的指针,再通过指针去取得对应元素的。所以,使用指针的效率比使用索引下标取数组值的效率要高,它少了一个转换过程。或者说,指针和数组的索引是一一对应的关系。
10.由于数组名指向的是数组的第一个元素,如果某个指针指向这个数组中的某个元素,那么可以说这个指针指向的就是一个子数组。例如arr是原始数组,那么parr+3是一个子数组,arr+4也是一个子数组。这使得我们可能访问到数组第一个元素之前的元素(即父数组中子数组之前的元素),比如-1、-2在操作上都是允许的,除非这样的访问超越了父数组的边界。

2.指针和数组之间的几个等价概念

          等价的方式              |      意义
--------------------------------|---------------------
&arr[i]    arr+i      parr+i    |  都表示index=i元素的地址
arr[i]     *(arr+i)   *(parr+i) |  都表示index=i元素的值

特别的,当i=0时:

&arr[0]    arr      parr      都表示数组第一个元素的地址
arr[0]     *(arr)   *(parr)   都表示数组第一个元素的值

3.指针运算

指针是变量,可以直接参与表达式的运算,指针是地址,可以进行地址运算。

有效的指针运算包括:

  1. 相同类型指针之间的相互赋值运算
  2. 指针与整数之间的加、减法运算。这种运算可以让指针前移或后移N个数组的元素
  3. 指向相同数组中元素的两个指针之间的减法或比较运算(指针与指针之间只能进行减法和比较),减法运算得到的结果是指针之间的元素个数(例如(arr+3) - arr + 1表示第1个元素到第4个元素之间的4个元素)
  4. 0赋值给指针的运算、0转换成指针类型的空、指针和0之间的比较
  5. 其它的运算方式都是非法的

对于指针和整数之间的加减法或指针的自增、自减运算,需要注意的是这些运算符之间的优先级以及从右向左计算的方式。

parr += 1表示将指针向后移动一位,等价于++parr

*++parr表示取下一个数组元素,因为一元运算符*++的优先级相同,它们从右向左运算。

*parr++表示取得parr当前指向的元素,但是parr已经指向下一个元素了。

指针之间可以比较大小,当然,只有指向同一数组的多个指针之间的比较才有意义。p和q两个指针,如果p指向的元素在q指向的元素之前,那么p < q。通过比较指针,也可以很容易判断数组的访问是否越界。例如,判断指针指向的元素是否在第99个元素之后,对于只有100个元素的数组来说,这就是在判断越界。

parr > &arr[99]
parr > arr + 99  // 与上等价

同理,指向同一数组的多个指针之间可以进行减法运算(只能进行减法),指针之间的减法运算返回的是这两个指针之间的元素个数

4.指针、数组和函数

C语言是按值拷贝的。

但因为数组名本身就是指向第一个元素的指针,所以按值拷贝也只是拷贝这个指针,拷贝得到的指针副本仍然指向数组的第一个元素,并且通过这个指针能够遍历到后面的元素。

因为拷贝后得到的副本指针指向的仍然是函数外面的数组结构,所以在函数内部可以直接通过这个指针修改外部数组。

下面两种想要以数组作为参数的函数在行为上是等价的

void func1(int arr[]){}
void func1(int *parr){}

调用该函数时,都可以传递数组名或指针给它们:

int arr[];
int *parr;
parr = arr;

func1(arr);
func1(parr);

原文地址:https://www.cnblogs.com/f-ck-need-u/p/10590360.html

时间: 2024-10-26 20:38:58

C指针和数组的关系详解的相关文章

php中二维数组排序问题方法详解

合肥开源IT教育分享一篇<php中二维数组排序问题方法详解>的文章希望能够帮助在学习php的新手们,如果还有什么不懂的问题 可以关注我们的官方网站:www.kyitjy.com  豪华的名师团队,多位技术专家授课,多位核心研发工程师研发授课. PHP中二维数组排序,可以使用PHP内置函数uasort() 示例一: 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 回调函数如下:注意回调函数的返回值是负数或者是false的时候,表示回调函数的第一个参数在前,第二个参数在后排列 $per

Hibernate中的多对多关系详解(3)?

前面两节我们讲到了一对一的关系,一对多,多对一的关系,相对来说,是比较简单的,但有时,我们也会遇到多对多的关系,比如说:角色与权限的关系,就是典型的多对多的关系,因此,我有必要对这种关系详解,以便大家一起学习.下面来看例子: 首先我们必须建立二者的vo: public class Role implements Serializable {//这是role对象 private Integer rid; private String rdesc; private String rname; pri

【转】UML类图与类的关系详解

UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为一般关联关系和聚合关系(Aggregation),合成关系(Composition).下面我们结合实例理解这些关系. 基本概念 类图(Class Diagram): 类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础.类

安卓 Intent 与/intent-filter的关系详解。

Intent可以分为两种:显式Intent和隐式Intent;显式Intent:通过组件名字字段指定目标组件;因为开发者通常不知道其它应用程序的组件名字,所以,显式Intent通常用于应用程序内部消息传递;例如:一个Activity启动从属的服务或启动一个同级别的Activity;隐式Intent:不指定目标组件的名字(组件名字字段是空);隐式Intent经常用于激活其它应用程序中的组件;Android系统传递一个显式Intent消息对象到一个指定目标组件名字的实例,Intent消息对象中只用组

005-Scala数组操作实战详解

005-Scala数组操作实战详解 Worksheet的使用 交互式命令执行平台 记得每次要保存才会出相应的结果 数组的基本操作 数组的下标是从0开始和Tuple不同 缓冲数组ArrayBuffer(长度可变) 数组的进阶操作 多维数组 常用数组使用方法分析 1.可通过yield产生新的数组并赋值给变量 2.for循环中也同时可以添加if过滤器来过滤数据再产生新的数据 3.c.filter(_%2==0).Map(2*_)生产环境经常会使用的表达方法(重点) 4.数组和缓冲数组都是可以直接调用其

指针与数组的关系

指针与数组间关系紧密却一直没弄明晰,今天就来整理一下. ①定义中的内涵 当我们在定义数组时,必须要同时指定其类型和大小:而对于指针,则只需要指定其类型. 之所以数组需要指定大小,是因为系统会根据你所指定的大小为数组分配空间,例如int a[5],则数组得到sizeof(int)*5大小的存储空间(而且是连续的空间),不多不少. 而对于指针,系统只会为其分配空间,其指向地址并未分配,例如char *a,系统会为变量a分配空间,但*a(即a指向的地方)是随机的,系统不会为*a分配空间.这时候,你可以

UML类图与类的关系详解--转

http://www.uml.org.cn/oobject/201104212.asp 原文地址 UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为一般关联关系和聚合关系(Aggregation),合成关系(Composition).下面我们结合实例理解这些关系. 基本概念 类图(

c/c++(疑3) C语言指针与数组之间关系

c/c++ (疑1)数组和指针 c/c++(疑2) const extern 有了前面 两篇 基础,下面我们可以更深入的来介绍c/c++(疑3) C语言指针与数组之间关系 1 概述(C语言指针与数组之间关系) 指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址.指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到. 数组就是数组,其大小与元素的类型和个数有关.定义数组时必须指定其元素的类型和个数.数组可以存任何类型的数据,但不能存函数. 2    

C/C++指针和数组的关系

首先一个列子说明指针和数组真的不是一回事: 浅谈C中的指针和数组(一) 如果用硬是把数组和指针放在一个,一个放声明里一个放定义中,这里就能看到指针和数组名是不同的.这篇文章从符号表的角度分析一下指针和数组名的不同点,两种东西在数据访问的时候的不同点. 有关不同点,再来点更深层次的东西: 浅谈C中的指针和数组(二) 接下来看看指针和数组名的相同点,但是有两点特例.也即是sizeof和&操作的时候,他们表现的对象是不同的. 浅谈C中的指针和数组(三) C/C++指针和数组的关系