C语言中的数组是一种将标量数据聚集成更大数据类型的方式。C语言实现数组的方式非常简单,因此很容易翻译成机器代码。C语言一个不同寻常的特点是可以产生指向数组中元素的指针,并对这些指针进行运算。在机器代码中,这些指针会被翻译成地址计算。
3.6.1 基本原则
对于数据类型T和整型常数N,声明如下:
T A[N];
起始位置表示为工。这个声明有两个效果。首先,它在内存中分配一个L*N字节的连续区域,这里L是数据类型T的大小(单位为字节)。其次,它引人了标识符A,可以用来作为指向数组开头的指针,这个指针的值就是xa。可以用0~N-1的整数索引来访问该数组元素。数组元素i会被存放在地址为工xa+L*i的地方。
3.6.2 指针和引用
&是地址运算符,用于获取变量的地址。当&作用于一个对象上时,它返回该对象的地址。
*是解引用运算符,用于通过指针获取指向的值。当*作用于一个指针变量时,它返回指针指向的变量的值。
指针和引用的主要区别
内存分配:
- 指针:指针有自己的内存空间,存储的是某个变量的地址。
- 引用:引用只是一个别名,没有自己的内存空间,直接指向已存在的对象。
初始化:
- 指针:可以被初始化为NULL,表示没有指向任何对象。
- 引用:必须在声明时被初始化,并且必须是一个已有对象的引用。
使用方式:
- 指针:需要通过解引用操作符
*
来访问指向的对象。 - 引用:使用时会自动解引用,不需要显式解引用操作。
作为函数参数:
- 指针:作为函数参数时,需要对指针进行解引用才能操作对象。
- 引用:作为函数参数时,可以直接对对象进行操作,修改引用所指向的对象。
3.6.3 指针运算
C语言允许对指针进行运算,而计算出来的值会根据该指针引用的数据类型的大小进行伸缩。也就是说,如果p是一个指向类型为T的数据的指针,p的值为x,那么表达式
p+i的值为工十L*i,这里L是数据类型T的大小。
单操作数操作符&和*可以产生指针和问接引用指针。也就是,对于一个表示某个对象的表达式Expr,&Expr是给出该对象地址的一个指针。对于一个表示地址的表达式AExpr,*AExpr给出该地址处的值。因此,表达式Expr与*&Expr是等价的。可以对数组和指针应用数组下标操作。数组引用A[i]等同于表达式*(A+i)。它计算第i个数组元素的地址,然后访问这个内存位置。
扩展一下前面的例子,假设整型数组E的起始地址和整数索引i分别存放在寄存器%rdx和号%rcx中。下面是一些与E有关的表达式。我们还给出了每个表达式的汇编代码实现,结果存放在寄存器%eax(如果是数据)或寄存器%rax(如果是指针)中。
在这些例子中,可以看到返回数组值的操作类型为int,因此涉及4字节操作(例如movl)和寄存器(例如%eax)。那些返回指针的操作类型为int*,因此涉及8字节操作(例如leaq)和寄存器(例如%rax)。最后一个例子表明可以计算同一个数据结构中的两个指针之差,结果的数据类型为1ong,值等于两个地址之差除以该数据类型的大小。
3.6.4 嵌套的数组
当我们创建数组时,数组分配和引用的一般原则也是成立的。例如,声明
int A【5】【3】;
等价于下面的声明
typedef int row_t[3];
row3_t A[5];
数据类型row3_t被定义为一个3个整数的数组。数组A包含5个这样的元素,每个元素需要12个字节来存储3个整数。整个数组的大小就是4*5*3=60字节。
标签:计算机系统,指向,数据类型,3.6,地址,引用,数组,指针 From: https://blog.csdn.net/chenwinsagain/article/details/143375863