我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第22篇文章,点击查看活动详情
指针存储变量的地址或内存位置。
// 一般语法
datatype *var_name;
// 一个示例指针“ptr”,它保存整数变量的地址或保存其值可以通过“ptr”作为整数值访问的内存地址
int *ptr;
使用指针:
要在 C 中使用指针,我们必须了解以下两个运算符。
要将变量的地址访问为指针,我们使用返回该变量地址的一元运算符 &(与号)。 例如 &x 给了我们变量 x 的地址。
// 该程序的输出在不同的运行中可能不同。 请注意,程序会打印变量的地址,并且可以在不同的运行中为变量分配不同的地址。
#include <stdio.h>
int main()
{
int x;
// 打印 x 的地址
printf("%p", &x);
return 0;
}
另外一个运算符是一元*(星号),它用于两件事:
- 声明指针变量:在 C/C++ 中声明指针变量时,其名称前必须有 *。
// 演示指针变量声明的 C 程序。
#include <stdio.h>
int main()
{
int x = 10;
// 1)由于声明中有*,ptr就变成了指针变量(存放另一个变量地址的变量)
// 2) 由于 * 前面有 int,所以 ptr 是指向整数类型变量的指针
int *ptr;
// x 之前的 & 运算符用于获取 x 的地址。 x 的地址分配给 ptr。
ptr = &x;
return 0;
}
要访问存储在地址中的值,我们使用一元运算符 (*),它返回位于其操作数指定的地址的变量的值。 这也称为取消引用。
// 演示在 C 中使用 * 表示指针的 C 程序
#include <stdio.h>
int main()
{
// 一个普通的整数变量
int Var = 10;
// 保存 var 地址的指针变量。
int *ptr = &Var;
// 此行打印存储在 ptr 中的地址处的值。 存储的值是变量“var”的值
printf("Value of Var = %d\n", *ptr);
// 即使在同一台机器上,该行的输出在不同的运行中也可能不同。
printf("Address of Var = %p\n", ptr);
// 我们也可以使用 ptr 作为左值(赋值的左侧)
*ptr = 20; // Value at address is now 20
// 输出 20
printf("After doing *ptr = 20, *ptr is %d\n", *ptr);
return 0;
}
// 演示在 C++ 中将 * 用于指针的 C++ 程序
#include <iostream>
using namespace std;
int main()
{
// 一个普通的整数变量
int Var = 10;
// 保存 var 地址的指针变量。
int *ptr = &Var;
// 此行打印存储在 ptr 中的地址处的值。 存储的值是变量“var”的值
cout << "Value of Var = "<< *ptr << endl;
// 即使在同一台机器上,该行的输出在不同的运行中也可能不同。
cout << "Address of Var = " << ptr << endl;
// 我们也可以使用 ptr 作为左值(赋值的左侧)
*ptr = 20; // Value at address is now 20
// 输出 20
cout << "After doing *ptr = 20, *ptr is "<< *ptr << endl;
return 0;
}
- 输出 :
Value of Var = 10
Address of Var = 0x7fffa057dd4
After doing *ptr = 20, *ptr is 20
- 以下是上述程序的图示:
指针表达式和指针算术
可以对指针执行一组有限的算术运算。 指针可能是:
- 递增 (++)
- 递减 ( - )
- 可以将整数添加到指针( + 或 += )
- 可以从指针中减去整数(– 或 -=)
除非在数组上执行,否则指针算术是没有意义的。
注意:指针包含地址。 添加两个地址没有意义,因为不知道它会指向什么。 减去两个地址可以计算这两个地址之间的偏移量。
// C++ 程序来说明 C/C++ 中的指针运算
#include <bits/stdc++.h>
// 驱动程序
int main()
{
// 声明一个数组
int v[3] = {10, 100, 200};
// 声明指针变量
int *ptr;
// 将 v[0] 的地址分配给 ptr
ptr = v;
for (int i = 0; i < 3; i++)
{
printf("Value of *ptr = %d\n", *ptr);
printf("Value of ptr = %p\n\n", ptr);
// 将指针 ptr 增加 1
ptr++;
}
}
Output:Value of *ptr = 10
Value of ptr = 0x7ffcae30c710
Value of *ptr = 100
Value of ptr = 0x7ffcae30c714
Value of *ptr = 200
Value of ptr = 0x7ffcae30c718
数组名称作为指针
数组名称的作用类似于指针常量。 这个指针常量的值是第一个元素的地址。
例如,如果我们有一个名为 val 的数组,那么 val 和 &val[0] 可以互换使用。
// C++ 程序将数组名称说明为 C++ 中的指针
#include <bits/stdc++.h>
using namespace std;
void geeks()
{
// 声明一个数组
int val[3] = { 5, 10, 15};
// 声明指针变量
int *ptr;
// 将 val[0] 的地址分配给 ptr。 我们可以使用 ptr=&val[0];(两者相同)
ptr = val ;
cout << "Elements of the array are: ";
cout << ptr[0] << " " << ptr[1] << " " << ptr[2];
return;
}
// 驱动程序
int main()
{
geeks();
return 0;
}
输出:
Elements of the array are: 5 10 15
现在,如果将此 ptr 作为参数发送到函数,则可以以类似的方式访问数组 val。
指针和多维数组
考虑二维数值数组的指针表示法。 考虑以下声明
int nums[2][3] = { {16, 18, 20}, {25, 26, 27} };
一般来说,nums[i][j] 等价于 ((nums+i)+j)
| 指针符号 | 数组符号 | Value |
|---|---|---|
| *(*nums) | nums[0][0] | 16 |
| *(*nums + 1) | nums[0][1] | 18 |
| *(*nums + 2) | nums[0][2] | 20 |
| ((nums + 1)) | nums[1][0] | 25 |
| ((nums + 1) + 1) | nums[1][1] | 26 |
| ((nums + 1) + 2) | nums[1][2] | 27 |