如果想要更详细的了解指针原理、用途,请自行阅读《The C Programming Language》第 5 章。
指针是什么
指针其实就是一个包含一个变量的地址的变量。
如何定义指针
定义指针的方式很简单:类型 *指针名称;
即可。比如来声明一个变量名为a
,类型为int
的指针:
//一般指针不会在声明的时候初始化,如果初始化要使用地址,否则是在错误模式下处理数据的
int *a;
也就是比平时声明变量多了一个星号*
。
但是这里需要注意的是,声明时候的*a
表示的是指针a
包含的内存地址指向的内容,而a
包含的则是地址。
还需要注意的是,在 C 语言中,这个地址开始的一部分连续的空间将会划分给指针,以供存储地址,划出的大小由类型int
决定,一般int
为 2 个字节(这里的一个字节在有些英文文档中被称为“cell”)。而 C++ 中则需要new
来根据数据类型动态分配,而不是声明的时候就根据数据类型分配好了。
如何获取一个变量的地址
刚才说到指针其实就是一个包含一个变量的地址的变量。那么如何获取一个变量的地址呢?这样才可以给指针赋值。
方法很简单,使用&
符号,如下(a
就是上文声明的指针):
a=&b;
通过以上表达式,就将变量b
的地址赋值给指针a
,如果这时候使用*a
输出,就会发现输出的是b
的值。而且修改b
,输出*a
的值也会发生改变。
如果a
并不是指针,那么变量a
将会以十六进制存储变量b
的地址(一般是十六进制,有些环境、设备可能会有不同)。
下面展示输出一个变量地址的方法:
#include <stdio.h>
int main()
{
int a=10;
printf("%x\n",&a);
return 0;
}
输出结果如下:
bfeff2c8
Program ended with exit code: 0
可以看到,第一行的bfeff2c8
就是变量a
的地址。
赋值给一个指针
指针只负责存储地址,具体的值还是由变量存储。所以赋值给指针,就是将一个变量的地址赋值给它。如下:
#include <stdio.h>
int main()
{
int a=10;
int *b;
b=&a;
printf("%d\n",*b);
return 0;
}
输出:
10
Program ended with exit code: 0
指针的用途
听了上述描述,可能你会觉得指针的作用好像就是新建了一个软连接(symbolic link)或者创建了一个别名(alias)。但是指针最大的作用其实是搭配数组使用。
通过指针来使用数组
因为一个数组的地址其实是数组第一个元素的地址,而数组在地址上是连续存放的,所以可以对地址加 1 来实现控制数组。
如下(实际运行的时候可能会提醒,但是这里出于研究目的忽略提醒):
#include <stdio.h>
int main()
{
int a[5]={1,2,3,4,5};
int *b;
b=&a;
printf("数组地址:%x\n",&a);
printf("数组第一个元素:%d\n",*b);
b=b+1;
printf("是不是数组第二个元素:%d\n",*b);
return 0;
}
输出:
数组地址:bfeff2b0
数组第一个元素:1
是不是数组第二个元素:2
Program ended with exit code: 0
这里说明一下,如果在开发过程中,指针指向数组的话,请使用b=&a[0];
,这样不会出现提醒。
字符串和指针
字符串也是数组的一部分,所以也可以使用指针来实现一些功能,例如对比字符串(这个虽然不用指针也能写,但是使用指针的话,代码会变得更简洁)。
下面来演示一下指针访问字符串的例子(记得把指针类型换一下,换成char
,不然int
存放的会是 ASCII编码,而不是字符串的内存地址):
#include <stdio.h>
int main()
{
char a[20]="Hello! World!";
char *b;
b=&a[0];
printf("字符串的地址:%x\n",&a);
printf("字符串的第一个字符:%c\n",*b);
b=b+5;
printf("字符串的第六个字符:%c\n",*b);
return 0;
}
输出:
字符串的地址:bfeff2b0
字符串的第一个字符:H
字符串的第二个字符:!
Program ended with exit code: 0
其他用途
还有一些其他的用途,但是有上述的知识也不用过多解释了,讲一下思路即可。
更多维度的数组
C 语言支持二维数组,但是有时候需要更多维度,那么就需要使用指针来嵌套数组,这样可以实现更多维度的数组。
一般就是将指向多个数组的多个指针存放在一个数组中,然后通过上述方法来使用。
处理命令选项
这个一般使用不多,因为现在也没多少人使用命令行,都用图形化了,但是我还是要说一下。
先看一下我的另一篇博客《C语言中函数main的参数argc和argv是什么》。
argv
是一个指向一个字符串数组的指针,数组包含了参数,每个字符串就是一个参数,最后一个元素为0
。不过一般习惯使用多级指针来操作字符串。
这里介绍一下,一般的命令行程序,使用起来的命令如下:
程序名 -短选项 --长选项 内容
短选项为-
加一个字母,长选项一般为--
加一个单词。现在有些程序的短选项会省略-
。
短选项一般可以写到一起,举个例子:ls -a -f
也可以写成ls -af
。而这一功能的实现就需要使用指针(首先这是个存放了指向字符串指针的数组,其次指针真的更方便)。