通过变量名叫做直接引用,通过指针对变量的引用叫间接引用
间接引用的两种情况:
如果在一个指针变量中存放的是一个目标变量的地址叫做一级地址。
如果在一个指针变量中存放的是指向目标变量的地址的指针变量的地址,那么这个就叫做二级地址。
指针的指针如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示:
将这种关系转换为C语言代码:
int a =100;
int *p1 = &a;
int **p2 = &p1;
指针变量也是一种变量,也会占用存储空间,也可以使用&
获取它的地址。C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号*
。p1 是一级指针,指向普通类型的数据,定义时有一个*
;p2 是二级指针,指向一级指针 p1,定义时有两个*
。
数组中的每个元素可以是基本类型,也可以复合类型,因此也可以是指针类型。例如定义一个数组a由10个元素组成,每个元素都是int *指针:
int *a[10];
这称为指针数组。 int *a[10];和int **pa之间的关系:
int *a[10];
int **pa = &a[0];
main函数的标准原型应该是int main(int argc, char *argv[]);。 argc是命令行参数的
个数。而argv是一个指向指针的指针,为什么不是指针数组呢?因为前面讲过,函数原型中的[]表示指针而不表示数组,等价于char **argv。那为什么要写成char *argv[]而不写成char**argv呢?这样写给读代码的人提供了有用信息, argv不是指向单个指针,而是指向一个指针数组的首元素。数组中每个元素都是char *指针,指向一个命令行参数字符串。
打印命令行参数 :
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < argc; i++)
printf("argv[%d]=%s\n", i, argv[i]);
return 0;
}
编译执行:
$ gcc main.c
$ ./a.out a b c
argv[0]=./a.out
argv[1]=a
argv[2]=b
argv[3]=c
$ ln -s a.out printargv
$ ./printargv d e
argv[0]=./printargv
argv[1]=d
argv[2]=e
注意程序名也算一个命令行参数,所以执行./a.out a b c这个命令时, argc是4, argv如下图所示:
由于argv[4]是NULL,我们也可以这样循环遍历argv:
for(i=0; argv[i] != NULL; i++)