什么时候数组和指针是相同的

本文解析了C语言中数组与指针之间的关系,详细介绍了数组名如何被视为指针、数组下标如何转换为指针偏移量以及作为函数参数时数组与指针的等效性。

C语言标准对此作了如下说明:

规则1.表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针(具体释义见ANSI C标准第6.2.2.1节)。

规则2.下标总是与指针的偏移量相同(具体释义见ANSI C标准第6.3.2.1节)。

规则3.在函数的参数声明中,数组名被编译器当作指向该数组第一个元素的指针(具体释义见ANSI C标准第6.7.1节)。

 

1“表达式中的数组名”就是指针

例子:

声明如: int a[10],*p,i=2; 可以通过以下三种方法访问a[i]:

 (1)   p = a; p[i];

 (2)   p = a; *(p + i);

 (3)  p  = a + i; *p;

 

2  C语言把数组下标作为指针的偏移量

有一种说法,在编写数组算法时,使用指针比使用数组“更有效率”,这在通常情况下是错误的。在处理一维数组时,指针并不见得比数组快,C语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。

 

3 “作为函数参数的数组名”等同于指针

标准规定作为“类型的数组”的开参的声明应该调整为“类型的指针”;在my_function的调用上,无论实参是数组还是真的指针都是合法的。

my_function(int *turnip) {..}

my_function(int turnip[]) {...}

my_functin(int turnip[200]{...}) 

 

数组与指针可交换性的总结

1 用a[i]这样的形式以数组进行访问总是被编译器“改写”或解释为像*(a+1)这样的指针访问。

2 指针始终就是指针。它绝不可以改写成数给。你可以用下标形式访问指针,一般都是指针作为函数参数时,而且你知道实际传递给函数的是一个数组。

3 在特定的上下文中,也就是它作为函数的参数(也只有这种情况),一个数组的声明可以看作是一个指针。作为函数参数的数组(就是在一个函数调用中)始终会被编译器修改成为指向数组第一个元素的指针。

4 因此,当把一个数组定义为函数的参数时,可以选择把它定义为数组,也可以定义为指针,不管选择哪种方法,在函数内部事实上获得的都是一个指针。

5 在其他所有情况中,定义和声明必须匹配。如果定义了一个数组,在其他文件对它进行声明也必须把它声明为数组,指针也是如此。

 

### 数组指针的定义 数组指针是一种指向整个数组指针变量。它的定义形式为:`数据类型 (*指针名)[数组长度]`。例如,`int (*ps)[10] = &arr;` 表示 `ps` 是一个指向包含 10 个整型元素数组指针[^4]。 在 C 语言中,数组指针与普通指针有显著区别。普通指针(如 `int *p`)只能指向单个变量,而数组指针可以指向整个数组。这种区别主要体现在指针的类型信息上:数组指针包含了所指向数组的维度信息,这使得它在访问数组元素时具有更高的语义清晰度安全性。 ### 数组指针的使用场景 #### 多维数组操作 数组指针特别适用于处理多维数组。当传递一个多维数组给函数时,通常会使用数组指针来保持数组结构的信息。例如,若有一个二维数组 `int matrix[3][4];`,可以通过 `int (*ptr)[4] = matrix;` 来定义一个指向该数组每一行的指针。这样,在遍历或操作矩阵时,可以直接通过 `ptr[i][j]` 的方式访问每个元素,而无需担心指针运算带来的复杂性[^3]。 #### 函数参数传递 当需要将数组作为参数传递给函数时,使用数组指针可以保留数组的大小信息。这种方式比直接使用普通指针更加安全,因为编译器能够检查数组的边界,并确保传入的指针确实指向了一个正确大小的数组。例如,定义一个函数 `void processArray(int (*arr)[5])` 可以明确表示该函数期望接收的是一个指向 5 个整数的数组指针[^3]。 #### 动态内存分配 虽然动态内存分配通常涉及普通指针,但在某些情况下,也可以结合数组指针进行更复杂的内存管理。例如,使用 `malloc` 分配一块连续的内存空间用于存储多个相同大小的数组时,可以将返回的指针转换为数组指针类型,从而方便地按数组的方式访问内存。这种方法在实现类似“动态二维数组”的功能时非常有用[^1]。 #### 提高代码可读性维护性 在一些特定的应用场景中,比如需要对大型数据集进行结构化访问时,使用数组指针可以使代码更具可读性可维护性。通过显式地表达出指针所指向的数据结构,开发者可以更容易理解程序的行为,同时也减少了因误解指针类型而导致错误的可能性[^5]。 下面是一个简单的示例代码,演示了如何使用数组指针来打印一个一维数组的内容: ```c #include <stdio.h> void printArrayPtr(int (*ptr)[5]) { for (int i = 0; i < 5; i++) { printf("%d ", (*ptr)[i]); } printf("\n"); } int main() { int arr[5] = {1, 2, 3, 4, 5}; int (*ptr)[5] = &arr; printf("数组指针指向的数组元素值:\n"); printArrayPtr(ptr); return 0; } ``` 这段代码中,`printArrayPtr` 函数接受一个指向包含 5 个整数的数组指针,并利用这个指针访问并打印数组中的所有元素[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值