前言
这节会学到->运算符和struct结构 学完这些,再去学数据结构就很简单了! 加油!
资源在这
一、指向结构的指针
喜欢使用指针的人一定很高兴能使用指向结构的指针。至少有4个理由可以解释为何要使用指向结构的指针。第一,就像指向数组的指针比数组本身更容易操控(如,排序问题)一样,指向结构的指针通常比结构本身更容易操控。第二,在一些早期的C实现中,结构不能作为参数传递给函数,但是可以传递指向结构的指针。第三,即使能传递一个结构,传递指针通常更有效率。第四,一些用于表示数据的结构中包含指向其他结构的指针。
good,指针真不错!
实例
#include <stdio.h> #define LEN 20 struct names //定义结构体names { char first[LEN]; char last[LEN]; }; struct guy //定义结构体guy { struct names handle; char favfood[LEN]; char job[LEN]; float income; }; int main(void) { struct guy fellow[2] = { //这是一个结构嵌套,guy结构里嵌套了names结构 //初始化结构数组fellow,每个元素都是一个结构变量 {{"Ewen","Villard"}, "girlled salmon", "personality coach", 68112.00 }, {{"Rodney","Swillbelly"}, "tripe", "tabloid editor", 432400.00 } }; struct guy * him; //这是一个指向结构的指针 printf("address #1:%p #2:%p\n",&fellow[0],&fellow[1]); him = &fellow[0]; //告诉编译器该指针指向何处 printf("pointer #1:%p #2:%p\n",him,him+1);//两个地址 printf("him->income is $%.2f:(*him).income is $%.2f\n",him->income,(*him).income);//68112.00 //指向下一个结构,him加1相当于him指向的地址加84。names结构占40个字节,favfood占20字节,handle占20字节,float占4个字节,所以地址会加84 him++; printf("him->favfood is %s: him->handle.last is %s\n",him->favfood,him->handle.last); //因为有了上面的him++,所以指向的是favfood1[1], return 0; } 输出结果为 PS D:\Code\C\结构> cd "d:\Code\C\结构\" ; if ($?) { gcc structDemo02.c -o structDemo02 } ; if ($?) { .\structDemo02 } address #1:000000000061FD70 #2:000000000061FDC4 pointer #1:000000000061FD70 #2:000000000061FDC4 him->income is $68112.00:(*him).income is $68112.00 him->favfood is tripe: him->handle.last is Swillbelly
这个例题看懂了,自我感觉指针学的算是有个基本了解了!给自己点赞哦!
1.1 声明和初始化结构指针
声明结构指针很简单
struct guy * him;
声明结构指针很简单:struct guy * him; 首先是关键字 struct,其次是结构标记 guy,然后是一个星号(*),其后跟着指针名。这个语法和其他指针声明一样。 该声明并未创建一个新的结构,但是指针him现在可以指向任意现有的guy类型的结构。例如,如果barney是一个guy类型的结构,可以这样写: him = &barney; 和数组不同的是,结构名并不是结构的地址,因此要在结构名前面加上&运算符。 在本例中,fellow是一个结构数组,这意味着fellow[0]是一个结构。所以,要让 him指向fellow [ 0],可以这样写:
him = &fellow[0];
输出的前两行说明赋值成功。比较这两行发现,him指向fellow[0],him + 1指向fellow[1]。注意,him加1相当于him指向的地址加84。在十六进制中,874 - 820 = 54(十六进制)= 84 (十进制),因为每个guy结构都占用84字节的内存: names.first占用20字节,names.last占用20字节,favfood占用20字节,job占用20字节,income占用4字节(假设系统中float占用4字节).顺带一提,在有些系统中,一个结构的大小可能大于它各成员大小之和。这是因为系统对数据进行校准的过程中产生了一些“缝隙”。例如,有些系统必须把每个成员都放在偶数地址上,或4的倍数的地址上。在这种系统中,结构的内部就存在未使用的“缝隙”。
1.2 用指针访问成员
指针him指向结构变量fellow[0],如何通过him获得fellow[0]的成员的值?第1种方法也是最常用的方法:使用->运算符。该运算符由一个连接号(-)后跟一个大于号(>)组成。我们有下面的关系:
如果him == &barney,那么him->income 即是barney.income如果him == &fellow [ 0],那么him->income 即是 fellow [ 0 ] .income
换句话说,->运算符后面的结构指针和.运算符后面的结构名工作方式相同(不能写成him.income,因为him不是结构名)。 这里要着重理解him是一个指针,但是 him->income是该指针所指向结构的一个成员。所以在该例中,him->income是一个float类型的变量。 第2种方法是,以这样的顺序指定结构成员的值:如果him == &fellow[0],那么him == fellow[0]因为**&和***是一对互逆运算符。因此,可以做以下替代:
fellow[0].income == (*him) .income
必须要使用圆括号,因为.运算符比*运算符的优先级高。 总之,如果him是指向guy类型结构barney的指针,下面的关系恒成立: barney.income == (*him).income == him->income //假设him == &barney