指针
大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。因此,说指针是c语言的灵魂,一点都不为过。
内存与地址
计算机中,数据的存放在内存单元中,一个内存单元的大小是一字节。为了计算机更加方便的访问这些内存单元,可以给每个内存单元进行地址编号(不重复的),这样根据地址编号就可以准确的找到对应的内存单元。
指针与指针变量
指针
在对内存单元进行地址编码后,内存中的每个内存单元有一个独一无二的地址编码,每一个地址编码对应一个内存单元,因此可以形象的说一个地址编码指向一个内存单元。C语言中称这个地址为指针,也就是说指针就是地址。
指针变量
指针变量是变量,它是可以保存地址值的变量,也就是说指针变量是一种保存变量地址的变量。
指针变量的定义
指针变量的定义形式如下:
type * var_name;
例如
1| int *p;
定义一个整形指针变量,所以指针变量p只能保存整形变量的地址。
强调:* 符号标识该变量为指针类型,在定义多个指针变量时,每个指针变量前的 *不能省略,如果省略那么该变量就不是指针变量。
例如:
定义两个整形指针变量p 和 q。
int *p,q;
这种定义是错误的,其结果为定义了整形指针变量p和整形变量q。
指针变量初始化
指针变量的初始化和赋值有两种方法;一种是接收变量的地址为其赋值
int a = 10;//定义一个整形变量a
int * p = &a;//定义一个整形指针变量p,使指针变量p指向a所在的存储空间
另一种是与其他指针变量指向同一块存储空间
int a = 10;//定义一个整形变量a
int * p = &a;//定义一个整形指针变量p,使指针变量p指向a所在的存储空间
int * q = p;//定义一个整形指针变量q,使指针变量q指向指针变量p所指向的存储空间
在方法中出现的“&”是取地址运算符,其作用是获取变量a的地址。“&”在输入函数scanf()中也有出现,这是因为,数据只能由实参传递给形参,而不能反向传递,所以只能通过获取变量的地址从而对该变量进行操作。
在使用已定义指针变量时,变量名前不能加 * 例如:
int * p;
*p = &a; // 错误,指针变量是 p 而不是*p
该示例中*p = &a中 “ * ” 为取值运算符,*p表示指针变量指向的地址中存储的数据。
指针变量只能保存该指针变量所指向的基类型的地址,如int,char等还可以是是自定义数据类型如数组,结构体等。例如:
int *p;
char *q;
int a;
char b;
p = &a;// 正确,指针变量的基类型为int,变量a的类型为int
p = &b;// 错误,指针变量的基类型为int,变量b的类型为char
q = &a;// 错误,指针变量的基类型为char,变量a的类型为int
q = &b; // 正确,指针变量的基类型为char,变量b的类型为char
同类型的指针变量可以相互赋值
int a,*p1,*p2,b;//定义了两个整型变量a,b;两个整型指针变量为p1,p2
float *pf;// 定义一个浮点型指针变量pf
p1 = &a;// 指针变量p1指向变量a所在的存储空间
p2 = p1; // 指针变量p2也指向变量a所在的存储空间
pf = p1;// 错误 pf 和 p1虽然都是指针变量,但是他们的类型不同
指针变量的引用
所谓指针变量的引用,就是根据指针变量中存放的地址,访问该地址对应的变量。
访问指针变量所指向的变量的方式:
*指针变量名
int a = 3;//定义一个int型的变量a
int *p;//定义一个int*型的指针变量p
p = &a;//指针变量p指向变量a所在的存储地址
printf("%d", a);//通过变量名直接访问a的内容
printf("%d",*p);//通过地址间接访问变量a的内容
二级指针
我们知道指针变量是一个变量那么它就会有它的地址,二级指针就是用来保存指针变量的地址,进而会有三级、四级,这就是多级指针,
int a = 10;
int *p = &a;
int **pa = &p;
printf("a的地址:%p\n",&a);
printf("p的值 :%p\n",p);
printf("p的地址:%p\n",&p);
printf("pa的值 :%p\n",pa);
如果想通过 pa 访问 a ,先pa访问p,在**pa相当于p访问a
指针和数组
‘指针和数组两者在使用上很是相似,一部分人认为数组就是指针,其实指针和数组是没有关系。
数组是相同数据类型的集合,指针是地址,二者不可混淆。
指针数组
指针数组,即数组里存储的指针,数组中每个元素都是相同类型的指针。
指针数组的定义格式为:
类型 *数组名[数组大小]
定义一个含有 5 个整型指针变量的一维数组,并赋值
int *a[5] = {0};
int b[5]= {0,1,2,3,4};
int i = 0;
for(;i<5;i++)
{
a[i] = &b[i];
printf("%p\n",a[i]);
}
指针数组a中存储的是数组b各元素的地址,这样就可以通过指针数组中的每个元素间接的访问数组b。
for(i = 0;i<5;i++)
{
printf("%d\n",*a[i]);
}
数组指针
数组指针,即指向一维数组的指针
数组指针定义格式为
类型(指针名)[n]//n元素个数
数组指针是指向含有n个元素的一维数组的指针,数组下标也是数组类型的一部分,二维数组的本质就是每个元素是一维数组的一维数组,故通常使用数组指针指向二维数组的每一行,