介绍
指针算术是 C 语言中的一项强大功能,它允许你通过加或减数值来操作内存地址。指针算术最常见的应用之一是数组遍历。使用指针,我们可以高效地在数组中向前和向后移动。
在这个实验中,你将学习如何创建和初始化数组、设置指针来访问数组元素,以及使用指针算术来遍历数组。这项技术是 C 语言编程的基础,也是许多高级数据操作的基础。
创建一个基本的 C 程序
让我们先在 VSCode 编辑器中创建一个新的 C 文件。这个文件将包含我们使用指针进行数组遍历的主程序。
在 WebIDE 中,找到左侧的资源管理器面板,然后导航到
~/project目录。右键单击
project文件夹,选择“新建文件”。将文件命名为main.c。将以下基本的 C 程序结构复制到文件中:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n");
return 0;
}
按 Ctrl+S 或通过菜单选择“文件”>“保存”来保存文件。
让我们编译并运行这个程序,以确保一切设置正确。通过菜单选择“终端”>“新建终端”在 WebIDE 中打开一个终端,然后运行:
cd ~/project
gcc main.c -o main
./main
你应该会看到以下输出:
Array Traversal using Pointers
这确认了你的 C 开发环境正在正常工作。在接下来的步骤中,我们将修改这个程序以处理数组和指针。
声明和初始化数组与指针
在这一步中,我们将学习如何声明数组和指针,它们是使用指针进行数组遍历的基本组成部分。
理解数组和指针
C 语言中的数组是存储在连续内存位置的相同类型元素的集合。例如,一个包含 5 个元素的整数数组将在内存中依次为 5 个整数预留空间。
指针是一个存储另一个变量内存地址的变量。我们可以使用指针间接访问存储在特定内存地址的值。
让我们修改 main.c 文件,使其包含一个数组和一个指针:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
在这段代码中:
- 我们声明了一个包含 5 个元素的整数数组
arr,并将其初始化为 10、20、30、40 和 50。 - 我们声明了一个整数指针
ptr,稍后将用它来指向数组元素。 - 我们使用传统的数组表示法打印了数组元素。
编译并运行程序以查看数组元素:
gcc main.c -o main
./main
你应该会看到以下输出:
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
在下一步中,我们将把指针与数组关联起来,并使用指针访问数组元素。
将指针与数组关联并进行正向遍历
在这一步中,我们将建立指针与数组之间的联系,然后使用指针正向遍历数组。
将指针与数组连接
在 C 语言中,不带下标的数组名代表数组第一个元素的地址。这意味着我们可以直接将这个地址赋值给指针变量。
让我们修改 main.c 文件,将指针与数组关联起来并进行遍历:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare a pointer of integer type
int *ptr;
// Assign the address of the first element of the array to the pointer
ptr = arr; // This is equivalent to ptr = &arr[0]
// Print the array elements using array notation
printf("Array elements using array notation:\n");
for(int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// Print the array elements using pointer notation
printf("\nArray elements using pointer notation (forward traversal):\n");
for(int i = 0; i < 5; i++) {
printf("*(ptr + %d) = %d\n", i, *(ptr + i));
}
return 0;
}
在这段更新后的代码中:
- 我们将数组
arr第一个元素的地址赋值给了指针ptr。 - 我们添加了一个新的循环,使用指针算术来遍历数组。
- 表达式
*(ptr + i)访问的是内存位置ptr + i处的值。当i为 0 时,访问的是数组的第一个元素;当i为 1 时,访问的是第二个元素,依此类推。
编译并运行程序以查看结果:
gcc main.c -o main
./main
你应该会看到以下输出:
Array Traversal using Pointers
Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
Array elements using pointer notation (forward traversal):
*(ptr + 0) = 10
*(ptr + 1) = 20
*(ptr + 2) = 30
*(ptr + 3) = 40
*(ptr + 4) = 50
注意,这两种方法产生的输出是相同的。这表明指针算术可以像传统的数组索引一样用于访问数组元素。
实现用于数组遍历的指针递增
在上一步中,我们使用表达式 *(ptr + i) 来访问数组元素。虽然这种方法完全可行,但 C 语言提供了一种更简洁的方式来使用指针遍历数组:自增运算符 (++)。
当我们对指针进行自增操作时,它会根据所指向的数据类型的大小移动到下一个内存位置。对于整数指针,对其进行自增操作会使其移动到内存中的下一个整数位置。
让我们修改 main.c 文件,使用指针自增来遍历数组:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Declare and initialize a pointer to the first element of the array
int *ptr = arr; // Same as ptr = &arr[0]
// Print the array elements using pointer incrementation
printf("Array elements using pointer incrementation:\n");
for(int i = 0; i < 5; i++) {
printf("*ptr = %d\n", *ptr);
ptr++; // Move the pointer to the next element
}
// Reset the pointer to the beginning of the array
ptr = arr;
// Print all elements in a single line using pointer incrementation
printf("\nAll elements in a single line: ");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr++); // Print and then increment
}
printf("\n");
return 0;
}
在这段更新后的代码中:
- 我们在声明指针
ptr时直接对其进行初始化。 - 在第一个循环中,我们使用
*ptr来访问当前元素,然后使用ptr++移动到下一个元素。 - 第一个循环结束后,我们将
ptr重置为指向数组的起始位置。 - 在第二个循环中,我们使用后置自增运算符
*ptr++,它会先使用ptr的当前值,然后再对其进行自增操作。
编译并运行程序以查看结果:
gcc main.c -o main
./main
你应该会看到以下输出:
Array Traversal using Pointers
Array elements using pointer incrementation:
*ptr = 10
*ptr = 20
*ptr = 30
*ptr = 40
*ptr = 50
All elements in a single line: 10 20 30 40 50
这展示了如何使用指针自增来遍历数组。关键在于 ptr++ 在移动到下一个元素时会自动考虑数据类型的大小。
使用指针递减实现反向遍历
在前面的步骤中,我们已经学习了如何正向遍历数组。现在,让我们来学习如何使用指针递减来反向遍历数组。
要进行反向遍历,你需要:
- 初始化指针,使其指向数组的最后一个元素。
- 递减指针,从而反向遍历数组。
让我们修改 main.c 文件来实现反向遍历:
#include <stdio.h>
int main() {
printf("Array Traversal using Pointers\n\n");
// Declare and initialize an array of 5 integers
int arr[5] = {10, 20, 30, 40, 50};
// Forward traversal using pointer increment
int *ptr = arr;
printf("Forward traversal using pointer increment:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++;
}
printf("\n\n");
// Backward traversal using pointer decrement
// Point to the last element of the array
ptr = &arr[4]; // or ptr = arr + 4
printf("Backward traversal using pointer decrement:\n");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr--; // Move the pointer to the previous element
}
printf("\n\n");
// Alternative approach: Start from the last element and decrement in the loop condition
printf("Alternative backward traversal approach:\n");
for(ptr = &arr[4]; ptr >= arr; ptr--) {
printf("%d ", *ptr);
}
printf("\n");
return 0;
}
在这段更新后的代码中:
- 首先,我们使用指针递增进行正向遍历。
- 对于反向遍历,我们使用
ptr = &arr[4]将指针设置为指向数组的最后一个元素。 - 在循环内部,我们打印当前元素,然后使用
ptr--递减指针。 - 我们还展示了另一种方法,即将递减操作作为
for循环更新语句的一部分。
编译并运行程序以查看结果:
gcc main.c -o main
./main
你应该会看到以下输出:
Array Traversal using Pointers
Forward traversal using pointer increment:
10 20 30 40 50
Backward traversal using pointer decrement:
50 40 30 20 10
Alternative backward traversal approach:
50 40 30 20 10
这展示了如何使用指针算术来正向和反向遍历数组。通过递增和递减指针,你可以轻松地在数组中向任意方向移动。
总结
在本次实验中,你学习了如何在 C 语言编程中使用指针来遍历数组。以下是我们涵盖的关键概念:
数组和指针基础:
- C 语言中的数组将元素存储在连续的内存位置中。
- 指针存储内存地址,并可用于访问这些位置。
指针与数组的关系:
- 数组名(不带索引)代表数组第一个元素的地址。
- 我们可以将这个地址赋值给指针,从而建立与数组的连接。
正向遍历技术:
- 使用指针算术:
*(ptr + i) - 使用指针递增:先使用
*ptr,再使用ptr++ - 结合解引用和递增操作:
*ptr++
- 使用指针算术:
反向遍历技术:
- 将指针初始化为指向数组的最后一个元素:
ptr = &arr[size-1] - 使用指针递减:
ptr--以反向移动指针 - 循环条件可以检查指针何时到达数组的起始位置
- 将指针初始化为指向数组的最后一个元素:
指针算术是 C 语言中的一项强大功能,它能够实现高效的内存操作,并在处理数组和其他数据结构时提供灵活性。这种技术是更高级编程概念(如动态内存分配、链表和其他复杂数据结构)的基础。



