数组和指针的关系(区别)详解
我们知道,没有方括号和下标的数组名称实际上代表数组的起始地址。这意味着数组名称实际上就是一个指针。下面程序通过显示与间接运算符一起使用的数组名称来说明这一点。
图 1 存储在内存中的数组元素
既然 numbers 是 numbers[0] 的地址,那么给 numbers 添加值岂不是就可以获得数组中其他元素的地址了?这样想当然很有道理,但是,这里有一个知识点非常重要,即:在数学语句中使用指针时,它不像常规变量那样工作。
在 C++ 中,当给一个指针添加一个值的时候,实际上添加的值是把这个值乘以指针引用的数据类型的大小。换句话说,如果给 numbers 加 1,实际上就是给 numbers 加上 1Xsizeof(short);如果给 numbers 加 2,实际上就是给 numbers + 2Xsizeof(short),以此类推。在 PC 上,这意味着以下说法是真实的,因为 short(短整数)通常使用 2 个字节:
这种自动转换意味着数组中的元素可以通过使用其下标或通过将下标添加到指向数组的指针来检索。既然表达式 *numbers 与 *(numbers + 0) 相同,它可以检索数组中的第一个元素,那么 *(numbers + 1) 就可以检索第二个元素。同样,*(numbers+2) 即可检索第三个兀素,以此类推。图 2 显示了下标表示法和指针表示法的等价性。
图 2 下标符号和对应的指针符号
注意,向指针添加值时,括号非常重要。* 运算符优先于 + 运算符,所以表达式 *numbers + 1 不等于 *(numbers + 1)。表达式 *numbers + 1 的意思是将数组的第一个元素的内容加 1, 而 *(numbers + 1) 则是先给 numbers 加 1,然后对其进行解引用。
下面的程序使用指针符号显示了被访问数组的整个内容:
要理解数组名称和指针之间的密切关系,请看下面的程序。它定义了一个 double 数组和一个 double 指针,该指针分配了数组的起始地址。随后,不仅指针符号可以与数组名称一起使用,而且下标符号也可以与指针一起使用。
例如,&numbers[1] 得到 numbers[1] 的地址。在程序下面程序中就使用了该技巧。
// This program shows an array name being dereferenced with the * operator. #include <iostream> using namespace std; int main() { short numbers[] = {10, 20, 30, 40, 50}; cout << "The first element of the array is "; cout << *numbers << endl; return 0; }程序输出结果:
The first element of the array is 10
numbers 在上面程序中的作用类似于指向数组起始地址的指针,所以当 numbers 被解引用时,第一个元素被检索出来。那么,如何使用间接运算符来检索数组的全部内容呢?请记住,数组元素是一起存储在内存中的,如图 1 所示。图 1 存储在内存中的数组元素
既然 numbers 是 numbers[0] 的地址,那么给 numbers 添加值岂不是就可以获得数组中其他元素的地址了?这样想当然很有道理,但是,这里有一个知识点非常重要,即:在数学语句中使用指针时,它不像常规变量那样工作。
在 C++ 中,当给一个指针添加一个值的时候,实际上添加的值是把这个值乘以指针引用的数据类型的大小。换句话说,如果给 numbers 加 1,实际上就是给 numbers 加上 1Xsizeof(short);如果给 numbers 加 2,实际上就是给 numbers + 2Xsizeof(short),以此类推。在 PC 上,这意味着以下说法是真实的,因为 short(短整数)通常使用 2 个字节:
- *(numbers +1)是指地址 numbers + 1X2 处的值。
- *(numbers + 2)是指地址 numbers + 2X2 处的值。
- *(numbers + 3)是指地址numbers + 3X2 处的值。
这种自动转换意味着数组中的元素可以通过使用其下标或通过将下标添加到指向数组的指针来检索。既然表达式 *numbers 与 *(numbers + 0) 相同,它可以检索数组中的第一个元素,那么 *(numbers + 1) 就可以检索第二个元素。同样,*(numbers+2) 即可检索第三个兀素,以此类推。图 2 显示了下标表示法和指针表示法的等价性。
图 2 下标符号和对应的指针符号
注意,向指针添加值时,括号非常重要。* 运算符优先于 + 运算符,所以表达式 *numbers + 1 不等于 *(numbers + 1)。表达式 *numbers + 1 的意思是将数组的第一个元素的内容加 1, 而 *(numbers + 1) 则是先给 numbers 加 1,然后对其进行解引用。
下面的程序使用指针符号显示了被访问数组的整个内容:
//This program processes an array using pointer notation. #include <iostream> using namespace std; int main() { const int SIZE = 5; // Size of the array int numbers[SIZE]; // Array of integers // Get values to store in the array // Use pointer notation instead of subscripts cout << "Enter " << SIZE << " numbers: "; for (int count = 0; count < SIZE; count++) cin >> *(numbers + count); // Display the values in the array // Use pointer notation instead of subscripts cout << "Here are the numbers you entered:\n"; for (int count = 0; count < SIZE; count++) cout << * (numbers + count) << " "; cout << endl; return 0; }程序输出结果:
Enter 5 numbers: 5 10 15 20 25
Here are the numbers you entered:
5 10 15 20 25
要理解数组名称和指针之间的密切关系,请看下面的程序。它定义了一个 double 数组和一个 double 指针,该指针分配了数组的起始地址。随后,不仅指针符号可以与数组名称一起使用,而且下标符号也可以与指针一起使用。
// This program uses subscript notation with a pointer // variable and pointer notation with an array name. #include <iostream> #include <iomanip> using namespace std; int main() { const int NUM_COINS = 5; double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0}; double *doublePtr; // Pointer to a double // Assign the address of the coins array to doublePtr doublePtr = coins; // Display the contents of the coins array // Use subscripts with the pointer! cout << setprecision (2); cout << "Here are the values in the coins array:\n"; for (int count = 0; count < NUM_COINS; count++) cout << doublePtr [count] << " "; // Display the contents of the coins array again, but this time use pointer notation with the array name! cout << "\nAnd here they are again:\n"; for (int count = 0; count < NUM_COINS; count++) cout << *(coins + count) << " "; cout << endl; return 0; }程序输出结果:
Here are the values in the coins array:
0.05 0.1 0.25 0.5 1
And here they are again:
0.05 0.1 0.25 0.5 1
例如,&numbers[1] 得到 numbers[1] 的地址。在程序下面程序中就使用了该技巧。
// This program uses the address of each element in the array. #include <iostream> #include <iomanip> using namespace std; int main() { const int NUM_COINS = 5; double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0}; double *doublePtr; // Pointer to a double //Use the pointer to display the values in the array cout << setprecision (2); cout << "Here are the values in the coins array:\n"; for (int count = 0; count < NUM_COINS; count++) { doublePtr = &coins[count]; cout << *doublePtr << " "; } cout << endl; return 0; }程序输出结果:
Here are the values in the coins array:
0.05 0.1 0.25 0.5 1
double readings[20], totals[20];
double *dptr;
dptr = readings; // 使 dptr 指向 readings
dptr = totals; // 使 dptr 指向 totals
readings = totals; // 非法!不能改变 readings
totals = dptr; // 非法!不能改变 totals
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算