5.7 指针与指针之间的关系
到现在为止,对于指针的知识点基本上可以告一段落了,但是还有一个知识点没有讲解,那就是指针和指针之间的关系,首先通过下面的一段代码来了解最简单的相同类型指针之间的赋值。
include<stdio.h>
void main()
{
char*str="aaaabbbbccccdddd";
char*ptr;
ptr=str;
printf("%s\n",ptr);
return;
}
运行结果:
aaaabbbbccccdddd
在上面的代码中,先通过一个字符指针定义了一个字符串,然后定义了一个字符指针,通过把字符串的首地址赋值给定义的字符指针,通过printf语句成功打印出定义的字符串。如果定义的不是相同类型的字符指针,那么结果会怎样呢?看看下面的代码。
include<stdio.h>
void main()
{
char*str="aaaabbbbccccdddd";
int*ptr;
ptr=(int*)str;
while(*ptr!='\0')
{
printf("%s\n",ptr);
ptr++;
}
return;
}
运行结果:
aaaabbbbccccdddd
bbbbccccdddd
ccccdddd
dddd
通过图5-13来演示上面代码的运行结果,先通过字符指针定义一个字符串,接下来并没有定义一个相同类型的字符指针,而是定义了一个整型指针ptr,通过强制转换将字符指针的地址转换为整型指针,然后通过整型指针的移动来打印出其中的字符串。需要注意的是,整型指针的自加和自减的移动是每次4字节,而字符指针自加和自减的移动是每次1字节,同时指针所指向的内存区域是从起始地址开始到串结束符为止。
图 5-13 int型变量ptr所指向的内存结构
接下来看多重指针。在讲解多重指针之前,读者要明白的一点是,多重指针变量只能保存同级指针变量的值或它的第一级指针变量的地址。看看下面的代码。
include<stdio.h>
void main()
{
int a;
int*pa;
int**pb;
a=9;
pa=&a;
pb=&pa;
printf("&a=%d\n\n",&a);
printf("pa=%d\n",pa);
printf("&pb=%d\n",&pa);
printf("pa=%d\n\n",pa);printf("pb=%d\n",pb);
printf("&pb=%d\n",&pb);
printf("pb=%d\n",pb);
printf("pb=%d\n",pb);
return;
}
运行结果:
&a=1245052
pa=1245052
&pa=1245048
*pa=9
pb=1245048
&pb=1245044
*pb=1245052
**pb=9
通过图5-14来对上面代码的运行结果加以分析。先定义一个整型变量a,然后分别定义一个一维整型指针pa和二维指针pb,将a的地址保存在指针变量pa中,再将一维指针变量pa的地址保存在pb中,二维指针变量pb同样有自己的地址。从图5-14也可以看出,通过一个与pb结合可以得到变量a的地址。因为pb中保存的是指针变量pa的地址,所以与结合即可取出pa地址单元的值,即变量a的地址。pb再与结合就可得到变量a的值。注意,虽然定义二维指针pb时使用了两个号,但是这并不意味着可以对pb使用两个取地址运算符&,两个号的意思仅仅是指定义的指针变量保存的是一个指针的地址,而不是一个普通常量的地址,当然也可以将相同类型二维指针变量的值赋值给它。
图 5-14 int型变量a、指针pa、二重指针pb的内存结构