指针听说是永远的神,今天就来接触接触神吧~
通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。

指针介绍

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。
下面通过一个例子来简单了解下指针:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
int var1;
char var2[10];

printf("var1 变量的地址: %p\n", &var1);
printf("var2 变量的地址: %p\n", &var2);

return 0;
}

运行结果如下:

var1 变量的地址: 008FFAC4
var2 变量的地址: 008FFAB0

指针的使用

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。
例如下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int main ()
{
int var = 20; /* 实际变量的声明 */
int *ip; /* 指针变量的声明 */

ip = &var; /* 在指针变量中存储 var 的地址 */

printf("Address of var variable: %p\n", &var );

/* 在指针变量中存储的地址 */
printf("Address stored in ip variable: %p\n", ip );

/* 使用指针访问值 */
printf("Value of *ip variable: %d\n", *ip );

return 0;
}

运行结果:

Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20

空指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。
NULL 指针是一个定义在标准库中的值为零的常量。
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

指针的算术运算

指针是一个用数值表示的地址,所以指针有4种算术运算:++、–、+、-。

  • 指针的每一次递增,是指向下一个元素的存储单元。
  • 指针的每一次递减,是指向前一个元素的存储单元。
  • 指针在递增和递减时跳跃的字节数取决于指针所指向变量的数据类型长度,比如int是4个字节。

指针的递增运算

下面以指针的递增运算简单描述下指针的算术运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

const int MAX = 3;

int main()
{
int var[] = { 10,100,200 };
int i, * ptr;

//指针中的数组地址
ptr = var;
for (i = 0; i < MAX; i++)
{
printf("存储地址:var[%d] = %x\n", i, ptr);
printf("存储值:var[%d] = %d\n", i, *ptr);

ptr++;//移动到下一个位置
}
return 0;
}

运行结果:

存储地址:var[0] = 4c56f568
存储值:var[0] = 10
存储地址:var[1] = 4c56f56c
存储值:var[1] = 100
存储地址:var[2] = 4c56f570
存储值:var[2] = 200

因此,指针的递减运算也是一样的操作。

指针的比较

指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

const int MAX = 3;

int main()
{
int var[] = { 10,100,200 };
int i = 0, * ptr;

//指针中的数组地址
ptr = var;
while(ptr <= &var[MAX-1]) //如果变量指针所指向的地址小于或等于数组的最后一个元素的地址,则执行以下操作
{
printf("存储地址:var[%d] = %x\n", i, ptr);
printf("存储值:var[%d] = %d\n", i, *ptr);

ptr++;//移动到下一个位置
i++;
}
return 0;
}

运行结果:

存储地址:var[0] = 7370fb58
存储值:var[0] = 10
存储地址:var[1] = 7370fb5c
存储值:var[1] = 100
存储地址:var[2] = 7370fb60
存储值:var[2] = 200

指向指针的指针

指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

int main()
{
int var;
int* ptr;
int** pptr;

var = 3000;

/* 获取 var 的地址 */
ptr = &var;

/* 使用运算符 & 获取 ptr 的地址 */
pptr = &ptr;

/* 使用 pptr 获取值 */
printf("Value of var = %d\n", var);
printf("Value available at *ptr = %d\n", *ptr);
printf("Value available at **pptr = %d\n", **pptr);

return 0;
}

运行结果:

Value of var = 3000
Value available at ptr = 3000
Value available at *
pptr = 3000

评论