C++基础(22)C 和 C++ 中的指针 | 第 1 组(介绍、算术和数组)

1,009 阅读3分钟

我报名参加金石计划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